一道子串的题目
一、枚举
遍历每一个数组,将每一个数组前面的连续数组求和(从后往前);求和过程中,只要等于 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 ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1)
二、哈希表
设 p r e [ i ] pre[i] pre[i] 为 [ 0... i ] [0...i] [0...i] 里所有数的和,同理 p r e [ j ] pre[j] pre[j] 为 [ 0... j ] [0...j] [0...j] 里所有数的和;
有: p r e [ j − 1 ] = = p r e [ i ] − k pre[j-1]==pre[i]-k pre[j−1]==pre[i]−k,其中 [ j , i ] [j,i] [j,i]数组和为 k;
我们建立哈希表 mp,以和为键,出现次数为值。
我们从头开始遍历,并更新 mp 以及 计算。
运算 p r e [ i ] pre[i] pre[i] 和的时候,计算 p r e [ 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)