Leetcode-560-和为k的子数组
题目链接
题目描述
给你一个整数数组 nums 和一个整数 k ,
统计数组中和为 k 的连续子数组的个数。
注意: 元素有正负....!!
要求
时间复杂度:O(n)
思路
(感觉自己好笨....😔)
-
想到了用前缀和pre[i],从 pre[0]~pre[i-1] 中找 (pre[i]-k),
但一开始想着用二分...以为都是正数,pre非递减。。。
而且就算想错了, 也做不到O(n)..😭 -
前缀和 + 哈希
map<pre, cnt>
key 是前缀和, 记录值是这个前缀和出现的次数。遍历数组,计算 pre[i] 后, 从前面找 (pre[i]-k) 出现的次数 ,
从左往右边更新边计算,保证了 map[pre[i]−k] 里记录的下标范围是 [0, i) .
同时,可以不建立 pre 数组,直接用 pre 变量来记录 pre[i−1] 的答案即可。
\(\color{red}{边计算边更新很重要}\)
C++代码
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
int pre = 0, ans = 0, t;
int n = nums.size();
mp[0] = 1;
for (int i = 0; i < n; i++) {
pre += nums[i];
t = pre - k;
if (mp.find(t) != mp.end())
ans += mp[t];
mp[pre] ++;
}
return ans;
}
};