About 1 min
// 560. 和为K的子数组
class Solution {
public int subarraySum(int[] nums, int k) {
int[] sums = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
sums[i + 1] = sums[i] + nums[i];
}
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, 1); // 把前缀和 sums[0]=0 放进去
int count = 0;
for (int i = 0; i < nums.length; i++) {
// 当前元素包括自身的[0...i]的数组和
int sum = sums[i + 1];
count += map.getOrDefault(sum - k, 0);
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
return count;
}
}
前缀和 + 哈希表(记录前缀和出现的次数)
通过计算前缀和,我们可以将"和为 k 的连续子数组"问题转化为求解两个前缀和之差等于k的情况。
使用了一个哈希表 map 来记录前缀和出现的次数。这个哈希表的键是前缀和,值是前缀和出现的次数。
当我们遍历数组时,把一个从开始位置到当前元素(包括自己)的子数组分成两部分,前一部分的数组和是sum-k,后一部分的数组和是k。这个后一部分数组和是k的数组即为所求。
我们使用map来检查 sum-k 这一部分存在与否。如果存在,所求数组和是k的后半部分也存在。因此,我们可以通过 map.get(sum - k) 来获取到符合条件的子数组的个数。
并且,将当前元素包括自身的[0...i]的数组和,放入map中,次数+1。