29. 和为 k 的子数组
题目链接:
题目描述:
给定一个整数数组 nums 和一个整数 k,返回该数组中和为 k 的连续子数组个数。
题目示例:
输入:nums = [1,1,1], k = 2
输出:2
解释:[1,1] 和 [1,1](第二个和第三个元素)都满足条件。
前缀和 + 哈希表
这题的关键不是枚举子数组,而是盯住'以当前位置结尾'的子数组。
设 sum[i] 表示 [0, i] 的前缀和。若某个子数组 [x, i] 的和等于 k,那就有:
sum[i] - sum[x-1] = k
也就是:
sum[x-1] = sum[i] - k
所以,问题就变成了:在当前位置之前,有多少个前缀和等于 sum[i] - k。
这个地方没必要真的开一个前缀和数组。边遍历边累加前缀和,再用哈希表记录每个前缀和出现了几次,就够了。hash[0] = 1 这一步别漏,不然从下标 0 开始的子数组会被算漏。
前缀和解法代码(C++)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> hash;
hash[0] = 1;
int n = nums.size();
int sum = 0, ret = 0;
for(auto x : nums) {
sum += x;
if(hash.count(sum - k)) ++ret;
hash[sum]++;
}
return ret;
}
};


