560.和为k的子数组
给你一个整数数组 nums
和一个整数 k
,请你统计并返回 该数组中和为 k
的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例 1:
输入:nums = [1,1,1], k = 2 输出:2
示例 2:
输入:nums = [1,2,3], k = 3 输出:2
提示:
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
原题链接:560. 和为 K 的子数组 - 力扣(LeetCode)
思路一:暴力破解
代码1:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int count = 0;
int numslen = nums.size();
for( int i = 0; i < numslen; i++){
int sum = 0;
for( int j = i; j < numslen; j++){
sum += nums[j];
if(sum == k){
count++;
}
}
}
return count;
}
};
思路二:前缀和思想,计算每个位置的前缀和,并使用一个哈希表来存储每个前缀和出现的次数。在遍历的过程中,检查是否存在mp[j] - k的前缀和,如果存在,说明从某个位置到当前位置的连续子数组的和为k,将对应的次数累加到结果中。通过遍历一次数组,可以统计出和为k的连续子数组的个数,并且时间复杂度为O(n),其中n为数组的长度。
代码2:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
mp[0] = 1;
int count = 0, pre = 0;
for(auto num:nums){
pre += num;
if(mp.count(pre - k)){
count += mp[pre - k];
}
mp[pre]++;
// cout << mp[pre] << endl;
}
return count;
}
};