930. 和相同的二元子数组

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

子数组 是数组的一段连续部分。

方法一:哈希表

var numSubarraysWithSum = function(nums, goal) {
  let ret = 0;
  let map = new Map;
  let sums = 0;
  for(let num of nums){
    map.set(sums, (map.get(sums)||0 ) + 1);
    sums += num;
    ret += map.get(sums - goal) || 0;
  }
  return ret;
};

方法二:滑动窗口

/**
 * @param {number[]} nums
 * @param {number} goal
 * @return {number}
 */
var numSubarraysWithSum = function(nums, goal) {
  let len = nums.length
  let res = 0
  let sum = 0
  let l = r = 0
  while (r < len) {
      sum += nums[r]
      // 只有当 sum > S 的时候,才会收缩 l 指针
      while (sum > goal) {
          sum -= nums[l]
          l++
      }
      // 当条件符合的时候 -- 这里是重点
      if (sum === goal) {
          // 给定一个符合条件的最大窗口,要再分出一个指针来找出最多符合条件的连续子窗口
          // l 指针不能动,为的是保证 [l,r] 是符合条件的最大窗口,这样在这个窗口下有多少个连续符合的子窗口都能找到
          let tempL = l,tempSum = sum
          while(tempL<=r){
              if(tempSum === goal) res++
              tempSum-=nums[tempL]
              tempL++
          }
      }
      r++
  }
  return res;
};

示例 1:

输入:nums = [1,0,1,0,1], goal = 2
输出:4
解释:
如下面黑体所示,有 4 个满足题目要求的子数组:
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,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
posted @ 2021-07-08 10:40  尖子  阅读(45)  评论(0编辑  收藏  举报