Skip to main content

和为 k 的子数组

题目

给定一个整数数组和一个整数 k, 你需要找到该数组中和为 k 的连续的子数组的个数.

示例
输入: nums = [1, 1, 1], k = 2
输出: 2
解释: [1, 1][1, 1] 为两种不同的情况.
输入: nums = [1, 2, 3], k = 3
输出: 2
解释: 结果为 [1, 2][3]

题解

  • pre[i]pre[0..i] 所有元素的和, 那么 pre[i] = pre[i - 1] + nums[i], 因为 pre[i] 可以由 pre[i - 1] 递推过来
  • 同理, pre[j..i] 这个子数组和为 k 这个条件可以转化为 pre[i] = pre[j - 1] + k
  • 上面的公式也就是 pre[j - 1] = pre[i] - k

560-subarray-sum

上面这个图就很清晰, presum - k 其实就是子串的和, 我们的目的是计算 pre[i] - k 是否等于 presum - k. 换句话说, 就是在总和里减去 k 是否存在, 如果存在, 那么这就是一个和为 k 的子数组. 因此我们可以通过建立一个 hash 表, 将 pre[i] - k 设为 key, 而这个 key 出现的次数作为 val, 而我们最终的目的是统计 val.

Slide 1 of 9
var subarraySum = function (nums, k) {
// 前缀和要初始化一个 key 为 0, 因为初始化了一个 0, 所以它出现的次数就是 1
const map = new Map([[0, 1]])

let sum = 0
let count = 0

for (const num of nums) {
sum += num
if (map.has(sum - k)) {
count += map.get(sum - k)
}

if (map.has(sum)) {
map.set(sum, map.get(sum) + 1)
} else {
map.set(sum, 1)
}
}

return count
}