Subarray Sum Equals K LT560

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].

Idea 1. Brute force: find the sum of each subarray represented by a pair of integer 0 <= i <= j < nums.length, increment the count once the sum is equal to k.

Time complexity: O(n2)

Space complexity: O(1)

 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         int count = 0;
 4         
 5         for(int i = 0; i < nums.length; ++i) {
 6             int sum = 0;
 7             for(int j = i; j < nums.length; ++j) {
 8                 sum += nums[j];
 9                 if(sum == k) {
10                     ++count;
11                 }
12             }
13         }
14         
15         return count;
16     }
17 }

1.b using cumulative sum

Time complexity: O(n2)

Space complexity: O(n)

 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         int count = 0;
 4         int sz = nums.length;
 5         
 6         int[] cumuSum = new int[sz];
 7         cumuSum[0] = nums[0];
 8         for(int i = 1; i < sz; ++i) {
 9             cumuSum[i] = cumuSum[i-1] + nums[i];
10         }
11         
12         for(int i = 0; i < sz; ++i) {
13             if(cumuSum[i] == k) {
14                 ++count;
15             }
16             for(int j = i+1; j < sz; ++j) {
17                 if(cumuSum[j] - cumuSum[i] == k) {
18                     ++count;
19                 }
20             }
21         }
22         
23         return count;
24     }
25 }

The little trick here: cumuSum[i] = sum(nums[0], ...nums[i-1]), the sum of elements for the subarray nums[i:j] = cumuSum[j+1] - cumuSum[i], otherwise need to deal with the case when subarray starts at 0 index. 

 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         int count = 0;
 4         int sz = nums.length;
 5         
 6         int[] cumuSum = new int[sz+1];
 7         
 8         for(int i = 1; i <= sz; ++i) {
 9             cumuSum[i] = cumuSum[i-1] + nums[i-1];
10         }
11         
12         for(int i = 0; i < sz; ++i) {
13             for(int j = i+1; j <= sz; ++j) {
14                 if(cumuSum[j] - cumuSum[i] == k) {
15                     ++count;
16                 }
17             }
18         }
19         
20         return count;
21     }
22 }

Idea 2. Extending the cumulative sum idea listed on 1.b, the sum of elements between i and j is cumuSum[j] - cumuSum[i-1], if it is equal to k, then the subarray is found. We can make use of hashmap to store the pair of (sum, number of occurences of sum). Everytime the element is added to the cumulative sum, the number of times a subarray with sum k has occured is determined by the number of times sum - k has occured and then increment the count, in the meantime update the number of occurences of the cumulative sum.

Time complexity: O(n)

Space complexity: O(n)

Be careful, the cumulative sum start at 0, we need to check first and increment accordingly, as we don't have previous sum = 0

 1  class Solution {
 2      public int subarraySum(int[] nums, int k) {
 3          int count = 0;
 4          
 5          Map<Integer, Integer> sumCounts = new HashMap<>();
 6          int sum = 0;
 7           for(int num: nums) {
 8              sum += num;
 9              if(sum == k) {
10                  ++count;
11              }
12              count += sumCounts.getOrDefault(sum - k, 0);
13              sumCounts.put(sum, sumCounts.getOrDefault(sum, 0) + 1);
14          }
15          
16          return count;
17      }
18  }
 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         int count = 0;
 4         
 5         Map<Integer, Integer> sumCounts = new HashMap<>();
 6         int sum = 0;
 7          for(int num: nums) {
 9             sum += num;
10             if(sum == k) {
11                 ++count;
12             }
13             count += sumCounts.getOrDefault(sum - k, 0);
14             sumCounts.put(sum, sumCounts.getOrDefault(sum, 0) + 1);
15         }
16         
17         return count;
18     }
19 }

little trick like 1.b, add 0 to the hashmap, save the check on line 10 above, code is slightly more concise.

 1 class Solution {
 2     public int subarraySum(int[] nums, int k) {
 3         int count = 0;
 4         
 5         Map<Integer, Integer> sumCounts = new HashMap<>();
 6         sumCounts.put(0, 1);
 7         
 8         int sum = 0;
 9         for(int num: nums) {
10             sum += num;
11             count += sumCounts.getOrDefault(sum - k, 0);
12             sumCounts.put(sum, sumCounts.getOrDefault(sum, 0) + 1);
13         }
14         
15         return count;
16     }
17 }

猜你喜欢

转载自www.cnblogs.com/taste-it-own-it-love-it/p/10410209.html