Medium
o(n2)的方法太過naive不寫了,主要看O(n)的
寫個式子會比較好理解為什么里面要找hash.containsKey(sum - k)
反正有道題是preSum之類的跟這個很類似
i < j
sum[0, j] = nums[0] + nums[1] + nums[2] + ... + nums[j]
sum[0, i] = nums[0] + nums[1] + nums[2] + ... + nums[i]
sum[i + 1, j] = sum[0, j] - sum[0, i]
在本題代碼里,sum = sum[0, j]
我們要找的是所有使得sum[i ,j] == k中j - i + 1最大的情況(sum[0, j]也會被檢查是不是等于k)
所以每當我們得到一個sum[0, j]的時候,我們先判斷sum[0, j] == k or not. 如果等于,那很好,直接 j + 1就是長度;如果不等于,我們就要去找有沒有那么一個 subarray的和等于k呢,也就是sum[i+1, j] == k. 那如果有的話,我們就應該早就有sum[0, i] == sum - k 在hashMap里面當作前綴和存起來了.
image.png
class Solution {
public int maxSubArrayLen(int[] nums, int k) {
// [1,-1,5,-2,3]
// k = 3
// sum = 1 0 5 3 6
// i = 0 1 2 3 4
// sum - k = -2 -3 2 0 3
// maxLen= 4
//hashMap:
//key: sum before index i inclusively
//value : index i
//[1, 0]
//[0, 1]
//[5, 2]
//[3, 3]
int sum = 0;
int maxLen = 0;
Map<Integer, Integer> hash = new HashMap<>();
for (int i = 0; i < nums.length; i++){
sum += nums[i];
if (sum == k){
maxLen = i + 1;
} else if (hash.containsKey(sum - k)){
maxLen = Math.max(maxLen, i - hash.get(sum - k));
}
if (!hash.containsKey(sum)){
hash.put(sum, i);
}
}
// i < j
// sum[i + 1, j] = k
// sum[0,j] - sum[0,i] = sum[i + 1, j]
// sum - ? = k
return maxLen;
}
}