Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead.數組
Example 1:
Given nums = [1, -1, 5, -2, 3], k = 3,
return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest)優化Example 2:
Given nums = [-2, -1, 2, 1], k = 1,
return 2. (because the subarray [-1, 2] sums to 1 and is the longest)指針Follow Up:
Can you do it in O(n) time?code
O(N) 時間 O(N) 空間get
上來一看感受和209.Minimum Size Subarray Sum有點像,細思以後發現兩個根本不是一回事,209裏的數全是正數,這裏不是,沒什麼規律。
前綴和能夠解決,須要O(N^2)的時間。須要優化,因而能夠把前綴和存在hashmap裏,就只須要O(N)的時間了。
hashmap的key是前綴和,value是到第幾個數。注意key(表示前綴和)有可能重複(由於有負數)。
注意這道題不要先生成hashmap再遍歷map找和,由於key有可能重複,就會把以前的相同key覆蓋,越靠前的key產生的subarray越長,就會漏掉答案。
正確的做法是,一邊掃描數組生成hashmap一邊找和,這樣能確保找的都是前面的;同時若是遇到key重複了,先記錄下當前sum是否能夠找到和爲k,能夠的話記錄max,而後咱們丟掉這個key,保留最先的那個,由於最先的能夠生成的size更大,當前這個咱們也已經examine過了。hash
這道題的題意和209.Minimum Size Subarray Sum剛好相反。
不過這兩道題的解法徹底不一樣:
這道題因爲是求「equal」,因此用「hash」;209是求「大於等於」,因此是用尺取法,追擊指針(窗口)。
並且因爲兩道題的要求不一樣,它們的輸入數據也不一樣:這道題的輸入數據可正可負;209卻只能是非負數。it
public class Solution { public int maxSubArrayLen(int[] nums, int k) { int sum = 0; HashMap<Integer, Integer> map = new HashMap<>();//key:prefix和; value:到第幾個數 int max = Integer.MIN_VALUE; map.put(0, 0); for (int i = 1; i < nums.length + 1; i++) { sum += nums[i - 1]; int lookingfor = sum - k; if (map.containsKey(lookingfor)) { max = Math.max(max, i - map.get(lookingfor)); } if (!map.containsKey(sum)) map.put(sum, i); } if (max == Integer.MIN_VALUE) return 0; return max; } }