[leetcode] Subarray Sum Equals K

[leetcode] Subarray Sum Equals K

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:

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

Note:

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

分析:题目翻译一下:给定一个数组,要求找连续子数组之和为k的这样的子数组的个数。

第一个思路:首先想到用滑动窗口来做,保存两个指针,一个是left,一个right,sum保存着从left--right的值。如果sum比k小,那么就需要扩大窗口,right右移(注意这里可能会到达最右端的判断);如果sum==k,满足条件,窗口缩小,left右移;如果sum>k,窗口缩小,left右移。

整理代码如下:

 1 public int subarraySum(int[] nums, int k) {
 2         int left = 0;
 3         int right = 0;
 4         int sum = nums[0];
 5         int count = 0;
 6         while ( right < nums.length  && left < nums.length ){
 7             System.out.println(sum);
 8             if ( sum < k ){
 9                 if ( right == nums.length - 1 ){
10                     sum += nums[right];
11                     right++;
12                 }else if ( right < nums.length - 1){
13                     right ++;
14                     sum += nums[right];
15                 }else {
16                     break;
17                 }
18                 continue;
19             }else if ( sum == k ){
20                 count ++;
21                 sum -= nums[left];
22                 left++;
23                 continue;
24             }else if ( sum > k ){
25                 sum -= nums[left];
26                 left++;
27             }
28         }
29         return count;
30     }

    用全部正整数的数组调试了一下发现是对的。但是!没有办法满足负数和正数并存的情况,比如[-1,-1,1],这种就没有办法了。所以要寻找更好的方法。

思路2:这个题目,用传统的思路想,肯定是要计算sum(i,j),然后计算左右的任意两个位置和之后,进行比较。显然这种时间复杂度是O(n^2)。

这里我们注意到,sum(i,j)=sum(0,j)-sum(0,i-1),所以如果我们用一个map保存(0,each i in nums.lenght),也就是sum(0,i-1),那么时间复杂度可以降低为O(n)了。

代码如下:

 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         Map<Integer,Integer> map = new HashMap<>(); //记录sum,frequency
 4         int sum = 0;
 5         int result = 0;
 6         map.put(0,1);
 7         for ( int i = 0 ; i < nums.length ; i ++ ){
 8             sum += nums[i];
 9             if ( map.containsKey(sum - k) ){
10                 result += map.get(sum-k);
11             }
12             map.put(sum,map.getOrDefault(sum,0)+1);
13         }
14         return result;
15     }
16 }