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?
哈希表
复杂度
O(N) 时间 O(N) 空间
思路
上来一看感觉和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过了。
注意
这道题的题意和209.Minimum Size Subarray Sum恰好相反。
不过这两道题的解法完全不同:
这道题由于是求“equal”,所以用“hash”;209是求“大于等于”,所以是用尺取法,追击指针(窗口)。
而且由于两道题的要求不同,它们的输入数据也不同:这道题的输入数据可正可负;209却只能是非负数。
代码
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;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。