题目
暴力破解的时间复杂度为O(n^2),绝逼超时,代码如下:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
map<int,int> m;
for(int i=0;i<nums.size();i++)
{
int sum = 0;
for(int j=0;j<=i;j++)
{
sum += nums[j];
}
m.insert({i+1,sum});
}
int count = 0;
m.insert({0,0});
for(int i=0;i<m.size();i++)
{
for(int j=i+1;j<m.size();j++)
{
if(m[j]-m[i] == k)
count++;
}
}
return count;
}
};
这类问题的解法,在于一边计算一个元素的前缀和的时候,还要记录产生了哪些前缀和,也就是要为每个产生的前缀和创建hash表;
若是一个前缀和减去要找的数的结果也存在于hash表中,说明存放和为要找的结果的连续子序列;
而这题因为是求一个连续和出现的次数,因此以前缀和的次数作为hash的value;
题目还可以这么问,“给定一个整数数组和一个整数 k,你需要找到该数组中是否存在和为 k 的连续的子数组”;
代码如下:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> m;
m[0] = 1;
int sum = 0;
int count = 0;
for(int i=0;i<nums.size();i++)
{
sum += nums[i];
if(m.find(sum-k)!=m.end())
count += m[sum-k];
m[sum] ++;
}
return count;
}
};