560. Subarray Sum Equals K

问题:

给定数组(含有正数负数),求连续子集合和=k的子集合数。

Example 1:
Input:nums = [1,1,1], k = 2
Output: 2

Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

  

解法:

方法1:

暴力求解:l 代表左边,r 代表右边

用 l 遍历数组,

内部嵌套 r=l 开始遍历数组,依次求和,==k的时候,res++

tip:注意:由于中间可能含有负数,不能在==k之后,立马continue。

代码参考:

 1 class Solution {
 2 public:
 3     int subarraySum(vector<int>& nums, int k) {
 4         int l=0, r=0;
 5         int res=0;
 6         int tmpsum=0;
 7         for(l=0; l<nums.size(); l++){
 8             tmpsum=0;
 9             for(r=l; r<nums.size(); r++){
10                 tmpsum+=nums[r];
11                 if(tmpsum==k){
12                     res++;
13                 }
14             }
15         }
16         return res;
17     }
18 };

解法2:

前缀求和法:

每次求0~i的和,并把这个结果记录在hash表中,

因为数组中有正有负,因此同一个sum值,可能出现多次。hash的value则记录出现的次数,key记录该sum值

遍历右边,若存在满足要求的i~j的和( k=sum(i~j) ),那么

presum(j)=presum(i)+k

那么presum(i)=presum(j)-k

到当前的j为止,存在多少个presum(i),则有多少个可能满足要求。

res+=hash[presum(i)]

同时更新当前presum(j)到hash表中。

tip:注意:初始化,首先加入presum(0)有1个解到hash表中。

 1 class Solution {
 2 public:
 3     int subarraySum(vector<int>& nums, int k) {
 4         int l=0;
 5         int res=0;
 6         int presum=0;
 7         unordered_map<int,int>sumhash;
 8         //key:sum,value:same presum(0~i) happens cout
 9         //sum(i~j)=sum(0~j)-sum(0~i)=presum(j)-presum(i)
10         //presum(i)=presum(j)-sum(i~j)=presum(j)-k
11         sumhash.insert({0,1});
12         for(l=0; l<nums.size(); l++){
13             presum+=nums[l];
14             res+=sumhash[presum-k];
15             sumhash[presum]++;
16         }
17         return res;
18     }
19 };
原文地址:https://www.cnblogs.com/habibah-chang/p/12687087.html