【LeetCode 930.和相同的二元子数组】 滑动窗口

一.题目描述

和相同的二元子数组

给你一个二元数组 nums ,和一个整数 goal ,请你统计并返回有多少个和为 goal 的 非空 子数组。子数组 是数组的一段连续部分。

示例 1:
输入:nums = [1,0,1,0,1], goal = 2
输出:4
解释:
有 4 个满足题目要求的子数组:[1,0,1]、[1,0,1,0]、[0,1,0,1]、[1,0,1]

示例 2:
输入:nums = [0,0,0,0,0], goal = 0
输出:15

提示:

  • 1 <= nums.length <= 3 * 104
  • nums[i] 不是 0 就是 1
  • 0 <= goal <= nums.length

二.思路

求区间大于或者小于某个值并不困难,但是要解区间恰好等于某个值,那该如何求解呢?
我们不妨先假设:
A = A= A= 区间不大于于goal的总数量
B = B= B= 区间不大于于(goal-1)的总数量。
这样区间恰好等于goal的总数量: C = A − B C=A -B C=AB
那这道题不就转换成求连续子数组不大于goal&(goal-1)的个数嘛LeetCode.乘积小于K的子数组相似

在这里插入图片描述

三.源码

 public static int numSubarraysWithSum(int[] nums, int goal) {
     int a=getAns(nums,goal);//不大于goal的滑动窗口总数量
     int b=getAns(nums,goal-1);//不大于(goal-1)的滑动窗口总数量
     int c=a-b;//恰好等于goal的滑动窗口总数量
     return c;
  }
  public static int getAns(int[] nums,int goal){//求不大于goal的滑动窗口
     int left=0;
     int len=nums.length;
     int ans=0;
     int cnt=0;
     for(int right=0;right<len;right++){
        cnt+=nums[right];
        while(cnt>goal&&left<=right){
           cnt-=nums[left];
           left++;
        }
        ans+=right-left+1;
     }
     return ans;
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值