[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;
    }
}
相关文章
相关标签/搜索