和为K的子数组 - 前缀和+哈希表
1. 题目描述
给定一个整数数组和一个整数k,你需要找到该数组中和为k的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
2. 题解
public int subarraySum(int[] nums, int k) {
int count = 0, pre = 0;
HashMap < Integer, Integer > mp = new HashMap < > ();
mp.put(0, 1);
for (int i = 0; i < nums.length; i++) {
pre += nums[i];
if (mp.containsKey(pre - k)) {
count += mp.get(pre - k);
}
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
}
return count;
}
我们定义pre[i]为[0...i]里所有数的和。
假设和为k的子数组下标范围为[j...i],于是pre[i] - k = pre[j - 1]。
示例:nums = [3, 4, 7, 2, -3, 1, 4, 2], k = 7
遍历到nums[1]时,哈希表mp为{0=1, 3=1, 7=1},pre[1] - 7 = 0,哈希表中存在键0。
遍历到nums[2]时,哈希表mp为{0=1, 3=1, 7=1, 14=1},pre[2] - 7 = 7,哈希表中存在键7。
遍历到nums[5]时,哈希表mp为{0=1, 16=1, 3=1, 7=1, 13=1, 14=2},pre[5] - 7 = 7,哈希表中存在键7。
遍历到nums[7]时,哈希表mp为{0=1, 16=1, 18=1, 3=1, 20=1, 7=1, 13=1, 14=2},pre[7] - 7 = 13,哈希表中存在键13。
最后,和为k的连续的子数组的个数为4。
示例:nums = [3, 4, 7, 2, -3, 1, 4, 2, 1], k = 7
遍历到nums[8]时,哈希表mp为{0=1, 16=1, 18=1, 3=1, 20=1, 21=1, 7=1, 13=1, 14=2},pre[8] - 7 = 14,哈希表中存在键14。
最后,和为k的连续的子数组的个数为6。
符合条件的子数组个数多了两个,分别为[2, -3, 1, 4, 2, 1]和[4, 2, 1]。
哈希表中mp中14=2表示前缀和为14的子数组出现了两次,这两个子数组分别为[3, 4, 7]和[3, 4, 7, 2, -3, 1]。
参考:

浙公网安备 33010602011771号