1、题目描述
2、解题思路
设 sum[i] 表示 nums[0] + nums[1] + … + nums[i-1] 的和,称为第 i 位的前缀和。
于是,如果存在两个索引 i 和 j,使得 sum[j] - sum[i] == k,说明找到一个子数组 [i, j-1] ,子数组的和为 k。
定义一个 HashMap ,把 sum[i] 作为 key ,把 i 作为 value。如果有相同的 sum[i] ,我们保存 i 最小的那个。
从 i == sum.length-1 开始遍历 map:
遍历到的为 sum[i] ,如果在 map 中存在 sum[i]-k ,说明存在一个长度为 k 的子数组,现在我们得找到这个子数组的起始索引,即 map.get(sum[i]-k),于是我们统计从 map.get(sum[i]-k) 到 i-1 长度为,并更新 maxLength。
3、解题代码
class Solution {
public int maxSubArrayLen(int[] nums, int k) {
int length = nums.length;
int[] sum = new int[length + 1];
Map<Integer, Integer> map = new HashMap<>();
sum[0] = 0;
map.put(sum[0],0);
// sum[i] 表示从第 0 个元素到第 i 个元素的所有元素之和
for (int i = 1; i <= length; i++) {
sum[i] = sum[i - 1] + nums[i - 1];
// 把 sum[i] 的值作为 key,索引 i 作为 value 存储到 HashMap 中
if (!map.containsKey(sum[i])) {
map.put(sum[i], i);
}
}
int maxLength = 0; // 初始最大长度为 0
// 从 i = length-1 开始往前遍历 map ,
for (int i = length; i > maxLength; i--) {
// 假设遍历到 key == sum[i] ,如果 map 中存在 key == sum[i] - k,说明找到一个子数组和为 k
if (map.containsKey(sum[i] - k)) {
// 长度为:map.get(sum[i]) - map.get(sum[i]-k)
// map.get(sum[i]) 就是 i
maxLength = Math.max(maxLength, i - map.get(sum[i] - k));
}
}
return maxLength;
}
}