和为K的子数组
- 题解1 前缀和(哈希表)
- 题解2 暴力枚举(没过)
给你一个整数数组
nums
和一个整数
k
,请你统计并返回 该数组中和为
k
的
连续子数组的个数 。
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
提示:
1 <= nums.length <= 2 * 10^4
-1000 <= nums[i] <= 1000
-10^7 <= k <= 10^7
题解1 前缀和(哈希表)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int s = nums.size();
if(1 == s) {
if(k == nums[0]) return 1;
else return 0;
}
// Key = 前缀和 (对于当前i来说只与pre[i-1]有关,所以不需要前缀和数组)
// Value = 出现次数
// 即 A-B = Target 问题 (双指针shrink条件不确定【负数、正数、非递增】)
// 从左到右更新,保证0 < j < i
unordered_map<int, int> vmap;
// 和为0的连续子数组出现1次
// 给定初始值(0,1) 是因为有j=s的情况,即一直加到s满足sum(s)-k = 0,即sum(s) = k
// 如果不给这个初始值则会漏掉最开始出现该场景的这一次
vmap[0] = 1;
int pre{0}, valid{0};
for(auto& x : nums){
pre += x;
if(vmap.count(pre - k))
valid += vmap[pre - k];
vmap[pre]++;
}
return valid;
}
};
题解2 暴力枚举(没过)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int s = nums.size();
if(1 == s) {
if(k == nums[0]) return 1;
else return 0;
}
int valid{0};
for(int i = 0; i < s; i++){
int sum = 0;
for(int j = i; j >= 0; j--){
sum += nums[j];
if( sum == k ) valid ++;
}
}
return valid;
}
};