给你一个整数数组 和一个整数 ,请你统计并返回 该数组中和为
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
提示:
思路:前缀和 + 哈希表
- 先遍历一遍数组求出前缀和(为了防止越界检查,下标从 1 开始)
- 对于前缀和,当 [i+1~j] 这个区间的和为 k 时,则有 s[j] - s[i]=k
- 所以 求多少个 区间和为 k,就转换成了求有多少个(i,j)(j > i) s[j] - s[i]= k
- 如果暴力枚举(i,j)的话,需要
- 在哈希表中存储 s[x] 出现的个数,当遍历到当前元素时,只需要判断 (s[j] - k) 在哈希表是否存在,存在的话,在答案 res 上加上(s[j] - k)出现的次数(因为如果, s[j] - k 在 hash表中存在,那说明至少有一个 s[i] 满足,s[j] - s[i] == k,而s[j] - k 出现的次数,就是 对于当前 j,有多少个 i 满足,[i~j] 区间的和为 k)
时间复杂度:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
vector<int> s(nums.size() + 1, 0);
for(int i = 1; i <= nums.size(); i++) s[i] += (s[i-1] + nums[i-1]);
unordered_map<int, int> h;
int res = 0;
for(int i = 0; i <= nums.size(); i++){
if(h.count(s[i] - k)) res += h[s[i] - k];
h[s[i]] ++;
}
return res;
}
};