LeetCode 560. Subarray Sum Equals K (子數組之和等於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:
- 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].
題目標簽:Array, Map
題目給了我們一個nums array 和一個 k, 要我們找出有多少個子數組 之和是等於 k的。
一開始想到的是暴力解法,雖然能夠通過,但是n*n 始終是太慢。
這題可以利用HashMap,把出現過的sum 當作key 存入, 把這個sum 出現過的次數 當作value 存入。
遍歷nums array,一直更新sum,然後去map 裏找有沒有 sum - k,有的話說明 sum - k 是一個舊的sum,之前出現過。換句話說,新的sum - 舊的sum = k,說明 新的sum 減去 舊的sum,剩下的那一段的 和 等於k, 找到了一個子數組之和 = k的。然後在把新的sum 存入 map裏。
這題的關鍵就是,當我們知道了一個 sum(0,i) 和 sum(0,j)的話,我們也就知道了 sum(i+1, j)。
所以當我們知道了目前所有舊的sum, 當我們有了一個新的sum,我們可以利用map 去找到 新的sum - k 是不是在map裏存在。一旦存在,說明了我們找到了一個 子數組它的和為k。
要註意的是,這裏count +的是map 裏的value,而不是count++, 因為當你在map 裏找到了一個 sum - k的舊sum的時候,這個舊的sum 可能出現過2次,換句話說,可能有兩個長度不一樣的子數組,但是它們的和都等於 sum - k(因為有負數)。所以這裏要加上舊sum 的出現次數2,因為你找到了兩個不同的子數組它們的和都為k。
Java Solution:
Runtime beats 67.25%
完成日期:10/03/2017
關鍵詞:Array, HashMap
關鍵點:把所有出現過的sum存入map:sum為key,出現的次數為value;利用map來找k (新sum - k =? 任何舊sum)
1 class Solution 2 { 3 public int subarraySum(int[] nums, int k) 4 { 5 int count = 0; 6 int sum = 0; 7 8 Map<Integer, Integer> map = new HashMap<>(); 9 map.put(0, 1); // initial value sum = 0, occurrence = 1 for case sum = k, k - k = 0 counts 10 11 for(int i=0; i<nums.length; i++) // iterate nums array 12 { 13 sum += nums[i]; // update sum 14 15 if(map.containsKey(sum - k)) // if map has sum - k, meaning this new sum - old sum = k 16 count += map.get(sum - k); // previous sum might appear more than once 17 // this is why we need to add its value 18 map.put(sum, map.getOrDefault(sum, 0) + 1); // save new sum into map 19 } 20 21 return count; 22 } 23 }
參考資料:
https://discuss.leetcode.com/topic/87850/java-solution-presum-hashmap
LeetCode 題目列表 - LeetCode Questions List
LeetCode 560. Subarray Sum Equals K (子數組之和等於K)