LCR 010. 和为 K 的子数组
给定一个整数数组和一个整数 k
**,**请找到该数组中和为 k
的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2
输出: 2
解释: 此题 [1,1] 与 [1,1] 为两种不同的情况
示例 2:
输入:nums = [1,2,3], k = 3
输出: 2
提示:
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
法1:hash表
分析:
假设 nums = [1, 1, 1]
,k = 2
。我们逐步分析:
第一次迭代 (sum = 1
):
sum = 1
,我们检查sum - k = 1 - 2 = -1
,但-1
不在sumToCount
中。- 将当前前缀和
1
放入sumToCount
中,sumToCount
变为{0: 1, 1: 1}
。
第二次迭代 (sum = 2
):
sum = 2
,我们检查sum - k = 2 - 2 = 0
,此时0
在sumToCount
中,出现次数为1
。- 这意味着从索引
0
到当前元素的子数组和为k = 2
,因此我们增加count
(count += 1
)。 - 将当前前缀和
2
放入sumToCount
中,sumToCount
变为{0: 1, 1: 1, 2: 1}
。
第三次迭代 (sum = 3
):
sum = 3
,我们检查sum - k = 3 - 2 = 1
,此时1
在sumToCount
中,出现次数为1
。- 这意味着存在一个子数组的和为
k = 2
,因此我们增加count
(count += 1
)。 - 将当前前缀和
3
放入sumToCount
中,sumToCount
变为{0: 1, 1: 1, 2: 1, 3: 1}
。
时间复杂度:O(n)
空间复杂度:O(n)
var subarraySum = function(nums, k) {let sumToCount = new Map();sumToCount.set(0, 1); // 初始化 sumToCount,表示前缀和为 0 出现的次数为 1let sum = 0;let result = 0;for (let num of nums) {sum += num; // 累加当前元素的值// 如果 sum - k 存在于 map 中,说明存在子数组和为 kresult += sumToCount.get(sum - k) || 0; // 获取 sum - k 的出现次数,如果没有则为 0// 更新当前前缀和的出现次数sumToCount.set(sum, (sumToCount.get(sum) || 0) + 1);}return result;
};