leetcode560 - Subarray Sum Equals K - medium
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].
法1.brute force O(n^3):
头尾两两组合,然后再扫一遍得到sum,与k对比。
法2.加上sum[]改进O(n^2):
先O(n)时间算出sum数组,然后只按头尾两两组合,根据两sum相减的差去对比k。
法3.再加上two sum改进O(n):
用map记录当前位置之前某个sum出现过几次了。因为如果AB先后出现,目的是B-A=k,那么你先存过A的话,你到B的时候只要求A= B-K,那你就看看map里有没有出现过B(即当前sum)-k就好,如果有的话,给答案加上前面出现过的次数。然后根据当前sum更新一下map。
细节:用map做一开始一定要初始化一个map.put(0, 1);说明sum=0的有1个count了,相当于数组最开始留一个0的空。这样才能产生从第一个数到任意一个数的和,少了这个产生的都会减掉第一个数从而得到的是第二个数开始的和了。
实现3:
class Solution { public int subarraySum(int[] nums, int k) { if (nums == null) { return 0; } int sum = 0; int ans = 0; Map<Integer, Integer> map = new HashMap<>(); // P1: 一开始一定要加这句!!!不然无法产生从第一个数到某个数的和。 map.put(0, 1); for (int i = 0; i < nums.length; i++) { sum += nums[i]; if (map.containsKey(sum - k)) { ans += map.get(sum - k); } map.put(sum, map.getOrDefault(sum, 0) + 1); } return ans; } }
实现2:
class Solution { public int subarraySum(int[] nums, int k) { if (nums == null) { return -1; } long[] sums = new long[nums.length + 1]; for (int i = 1; i < sums.length; i++) { sums[i] = sums[i - 1] + nums[i - 1]; } int ans = 0; for (int i = 0; i < sums.length; i++) { for (int j = i + 1; j < sums.length; j++) { if (sums[j] - sums[i] == k) { ans++; } } } return ans; } }