[LeetCode 560] 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].

 

 

Solution 1.  Prefix Sum, O(N^2) runtime, O(N) space

1. compute a prefix sum of the input array;

2. for each subarray interval, check its sum equals to k, add 1 to the result counter if so. This step takes O(N^2) time.

 

class Solution {
    public int subarraySum(int[] nums, int k) {
        int n = nums.length;
        int[] prefixSum = new int[n + 1];
        for(int i = 1; i <= n; i++) {
            prefixSum[i] = prefixSum[i - 1] + nums[i - 1];
        }
        int count = 0;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j <= n; j++) {
                if(prefixSum[j] - prefixSum[i] == k) count++;
            }
        }
        return count;
    }
}

 

Solution 2. Prefix Sum with HashMap, O(N) runtime and space

1. Keep a running prefix sum and a hash map that stores the count of each different prefix sum value;  Add (0, 1) to the hashmap, representing a sum of 0 for empty interval.

2. for a given prefix sum ps, check if there are prefix sums that equal to ps - k. Any such prefix sum of ps - k means there is an interval with sum k. So the number of the current prefix sum ps - k represents the number of subarrays that end at the current index and have sum K. Add this count to the final answer. 

3. add the current prefix sum to the hash map for later checks.

 

This solution can be easily modified to get all intervals that sum to k. Just augment the value in hashmap to have the current element index.

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        int prefixSum = 0, count = 0;
        map.put(0, 1);
        for(int i = 0; i < nums.length; i++) {
            prefixSum += nums[i];
            count += map.getOrDefault(prefixSum - k, 0);        
            map.put(prefixSum, map.getOrDefault(prefixSum, 0) + 1);
        }
        return count;
    }
}

 

Related Problems

[LeetCode 525] Contiguous Array

[LeetCode 1371] Find the Longest Substring Containing Vowels in Even Counts

[AtCoder] Multiple of 2019

[LeetCode 1477] Find Two Non-overlapping Sub-arrays Each With Target Sum

posted @ 2019-09-29 06:26  Review->Improve  阅读(409)  评论(0编辑  收藏  举报