Skip to content

Latest commit

 

History

History
57 lines (45 loc) · 1.87 KB

560-SubarraySumEqualsK.md

File metadata and controls

57 lines (45 loc) · 1.87 KB

和为 K 的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

提示:

  • 1 <= nums.length <= 2 * 10^4
  • -1000 <= nums[i] <= 1000
  • -10^7 <= k <= 10^7

思路:

  1. 初始化:创建一个 Map 对象 mp 来存储前缀和出现的次数,键为前缀和,值为出现次数。初始化时,将 0 的计数设置为 1,因为从数组开始处到任意处的和为 0 的子数组至少有一个(空子数组)。
  2. 遍历数组:遍历数组 nums 中的每个数字,计算当前位置的前缀和 pre。
  3. 更新计数:对于每个前缀和 pre,检查 pre - k 是否存在于 Map 中。如果存在,说明找到了一个和为 k 的子数组,因为当前前缀和与之前的某个前缀和之差等于 k。将这个子数组的数量累加到 count 中。
  4. 更新前缀和:无论 pre 是否已经存在于 Map 中,都更新它的计数。如果不存在,就添加到 Map 中,并设置计数为 1;如果已存在,就将计数加 1。
  5. 返回结果:遍历完数组后,返回找到的和为 k 的子数组的数量。

时间复杂度:O(n),其中 n 是数组 nums 的长度。每个元素只被遍历一次。 空间复杂度:O(n),在最坏的情况下,每个前缀和都可能不同,因此 Map 中可能存储了所有前缀和的计数。

var subarraySum = function (nums, k) {
  const mp = new Map();
  mp.set(0, 1);
  let count = 0,
    pre = 0;
  for (const x of nums) {
    pre += x;
    if (mp.has(pre - k)) {
      count += mp.get(pre - k);
    }
    if (mp.has(pre)) {
      mp.set(pre, mp.get(pre) + 1);
    } else {
      mp.set(pre, 1);
    }
  }
  return count;
};