做网站标题头像网店推广
一道子串的题目
一、枚举
遍历每一个数组,将每一个数组前面的连续数组求和(从后往前);求和过程中,只要等于 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;// 初始和为0mp[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];}//更新mpmp[pre]++;}return count;}
};
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)