[Leetcode] Maximum Size Subarray Sum Equals k 找和爲k的最長子數組

Maximum Size Subarray Sum Equals k

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;
    }
}
相關文章
相關標籤/搜索