和为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]
哈希表中mp14=2表示前缀和为14的子数组出现了两次,这两个子数组分别为[3, 4, 7][3, 4, 7, 2, -3, 1]

参考:

posted @ 2020-12-23 10:46  gzhjj  阅读(224)  评论(0编辑  收藏  举报