💡 【LeetCode Hot100】和为 K 的子数组 | 前缀和+哈希表,Java实现!图解+代码,小白秒懂!
✏️ 题目链接: 560. 和为 K 的子数组
📌 题目描述
给定一个整数数组 nums 和一个整数 k,请找到该数组中和为 k 的连续子数组的个数。
示例:
输入:nums = [1,1,1], k = 2
输出:2
解释:连续子数组 [1,1] 和 [1,1] 的和均为 2。
🧠 解题思路
❗ 核心难点
如何高效计算所有和为 k 的子数组?
方法:前缀和 + 哈希表(黄金思路)✨
关键步骤:
- 前缀和定义:
preSum[i]表示前i个元素的和。 - 哈希表记录:存储前缀和出现的次数,用于快速查询。
- 遍历数组:
- 计算当前前缀和
sum。 - 检查哈希表中是否存在
sum - k,存在则累加次数。 - 将当前前缀和存入哈希表。
- 计算当前前缀和
🎨 图解示例
输入数组:
nums = [1, 2, 3], k = 3
步骤1:初始化
preSumMap = {0:1} // 初始前缀和为0,出现1次
sum = 0, count = 0
步骤2:遍历数组
元素1: sum=1 → sum-k=1-3=-2 → 不在map → count=0 → map更新为 {0:1, 1:1}
元素2: sum=3 → sum-k=0 → map中存在0 → count+=1 → count=1 → map更新为 {0:1, 1:1, 3:1}
元素3: sum=6 → sum-k=3 → map中存在3 → count+=1 → count=2 → map更新为 {0:1, 1:1, 3:1, 6:1}
结果:
count = 2(对应子数组 [1,2] 和 [3])
🚀 代码实现
import java.util.HashMap;
import java.util.Map;
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer, Integer> preSumMap = new HashMap<>();
preSumMap.put(0, 1); // 初始化前缀和为0的次数为1
int sum = 0; // 当前前缀和
int count = 0; // 结果计数器
for (int num : nums) {
sum += num; // 计算当前前缀和
// 检查是否存在 sum - k 的前缀和
if (preSumMap.containsKey(sum - k)) {
count += preSumMap.get(sum - k);
}
// 更新当前前缀和的出现次数
preSumMap.put(sum, preSumMap.getOrDefault(sum, 0) + 1);
}
return count;
}
}
💡 复杂度分析
- 时间复杂度:O(n) → 只需遍历数组一次。
- 空间复杂度:O(n) → 哈希表存储前缀和,最坏情况下需要存储 n 个不同前缀和。
🌟 总结
- 前缀和核心思想:通过差值快速定位子数组范围。
- 哈希表优化:避免重复计算,将时间复杂度从 O(n²) 降至 O(n)。
- 适用场景:连续子数组求和问题、统计特定和的出现次数。
LeetCode 560题:前缀和+哈希表解法
622

被折叠的 条评论
为什么被折叠?



