用普通的前缀和解法会超时
class Solution {
private:
vector<int> preSum;
public:
int subarraySum(vector<int>& nums, int k) {
int size = nums.size();
preSum.resize(size + 1, 0);
for (int i = 1; i <= size; i++)
preSum[i] = preSum[i - 1] + nums[i - 1];
int cnt = 0;
for (int i = 1; i <= size; i++)
{
for (int j = 0; j < i; j++)
{
if (preSum[i] - preSum[j] == k)
cnt++;
}
}
return cnt;
}
};
这里要进行优化
class Solution {
private:
map<int, int> mp;
public:
int subarraySum(vector<int>& nums, int k) {
int cnt = 0, sum = 0;
mp[0] = 1; //防止出现一个数、多个数相加正好为k的情况
for (int i = 0; i < nums.size(); i++)
{
sum += nums[i];
int n = sum - k;
if (mp[n] > 0)
cnt += mp[n]; //不是加1而是加mp[n],因为可能有不止一个连续和等于n
mp[sum]++;
}
return cnt;
}
};
这里一开始觉得在map里找的sum - k是连续的和,可是再加上刚刚的num[i]能保证连续吗?这是个误区,sum - k并不一定要和nums[i]一起,并且mp存储的就是连续的和,只要在mp中找到就一定是连续的。就比如nums = [1,2,3], k = 3
,再最后加上3后sum为6,n就是3,在mp中也找到了3,而这个3是1+2得到的。