一道子串的题目
一、枚举
遍历每一个数组,将每一个数组前面的连续数组求和(从后往前);求和过程中,只要等于 k 就停下,并计数。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int count = 0;
for (int start = 0; start < nums.size(); ++start){
int sum = 0;
for (int end = start; end >= 0; end--){
sum += nums[end];
if(sum == k){
count++;
}
}
}
return count;
}
};
时间复杂度:O(n2)O(n^2)O(n2)
空间复杂度:O(1)O(1)O(1)
二、哈希表
设 pre[i]pre[i]pre[i] 为 [0...i][0...i][0...i] 里所有数的和,同理 pre[j]pre[j]pre[j] 为 [0...j][0...j][0...j] 里所有数的和;
有:pre[j−1]==pre[i]−kpre[j-1]==pre[i]-kpre[j−1]==pre[i]−k,其中 [j,i][j,i][j,i]数组和为 k;
我们建立哈希表 mp,以和为键,出现次数为值。
我们从头开始遍历,并更新 mp 以及 计算。
运算 pre[i]pre[i]pre[i] 和的时候,计算 pre[j−1]pre[j-1]pre[j−1] 是否存在于 mp 中,如果不在就将 mp 中键为 pre[i]和 的值+1,也就是所谓的更新 mp。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
// 初始和为0
mp[0] = 1;
int count = 0, pre = 0;
for(auto& x:nums){
//计算 pre[i]
pre += x;
//查找 pre[j-1] 是否存在于哈希表中
if(mp.find(pre-k) != mp.end()){
count += mp[pre-k];
}
//更新mp
mp[pre]++;
}
return count;
}
};
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)