325 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.
Note: The sum of the entirenumsarray is guaranteed to fit within the 32-bit signed integer range.
Example 1:
Givennums=[1, -1, 5, -2, 3]
,k=3
,
return4
. (because the subarray[1, -1, 5, -2]
sums to 3 and is the longest)
Example 2:
Givennums=[-2, -1, 2, 1]
,k=1
,
return2
. (because the subarray[-1, 2]
sums to 1 and is the longest)
Follow Up: Can you do it in O(n) time?
这题首先算个prefix sum,然后再边loop边找需要的prefix sum的值,如果找到的话,我们算一下长度。hashmap里存的是要找的值,和符合这些值的那些位置。嘛,discuss上有另一种更省时间的写法,也贴上来参考。后来发现,其实不用存所有位置,因为要求的是max,然后现在的i减去靠前面的那些点一定比靠后面的大,所以每个presum只用存第一次找到的位置就ok了。
public int maxSubArrayLen(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return 0;
}
int n = nums.length;
int maxLen = 0;
int[] preSum = new int[n + 1];
for (int i = 1; i <= n; i++) {
preSum[i] = nums[i - 1] + preSum[i - 1];
}
// <preSum we need to find, first location that need this preSum>
HashMap<Integer, Integer> hm = new HashMap<>();
for (int i = 0; i <= n; i++) {
if (hm.containsKey(preSum[i])) {
maxLen = Math.max(maxLen, i - hm.get(preSum[i]));
}
if (!hm.containsKey(preSum[i] + k)) {// 如果发现不存在的话,每次都要更新一下hm
hm.put(preSum[i] + k, i);
}
}
return maxLen;
}
public int maxSubArrayLen(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return 0;
}
int n = nums.length;
int maxLen = 0;
int[] preSum = new int[n + 1];
for (int i = 1; i <= n; i++) {
preSum[i] = nums[i - 1] + preSum[i - 1];
}
// <preSum we need to find, locations that need this preSum>
HashMap<Integer, List<Integer>> hm = new HashMap<>();
for (int i = 0; i <= n; i++) {
if (hm.containsKey(preSum[i])) {
List<Integer> tmp = hm.get(preSum[i]);
for (Integer elem : tmp) {
maxLen = Math.max(maxLen, i - elem);
}
}
List<Integer> tmp;
if (hm.containsKey(preSum[i] + k)) {
tmp = hm.get(preSum[i] + k);
} else {
tmp = new ArrayList<>();
}
tmp.add(i);
hm.put(preSum[i] + k, tmp);
}
return maxLen;
}
discuss的clean solution:
public int maxSubArrayLen(int[] nums, int k) {
int sum = 0, max = 0;
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
sum = sum + nums[i];
if (sum == k) max = i + 1;
else if (map.containsKey(sum - k)) max = Math.max(max, i - map.get(sum - k));
if (!map.containsKey(sum)) map.put(sum, i);
}
return max;
}
Last updated
Was this helpful?