Q560 和为 K 的子数组
目录
题目:给你一个整数数组
nums和一个整数k,请你统计并返回该数组中和为k的连续子数组的个数。
1 解题核心思路
1.1 1. 为什么用前缀和?
题目要求相邻子数组的和等于 K,前缀和天然适合处理区间和:
$$preSum[r] - preSum[l] = K \iff preSum[l] = preSum[r] - K$$
1.2 2. 为什么用哈希表?
要从大量子数组中快速找出满足条件的数量。暴力双 for 循环复杂度 $O(n^2)$,哈希表可以降到 $O(n)$。
哈希表的核心作用:空间换时间——当题目既要计算子数组情况,又要从子数组中快速查找满足条件的项时,哈希表是首选工具。
1.3 3. 哈希表存什么?
| 场景 | 哈希表记录 |
|---|---|
| 求数量(本题) | val → count(前缀和 → 出现次数) |
| 求最大/最小长度 | val → index(前缀和 → 首次下标) |
2 算法步骤
- 遍历数组,维护当前前缀和
sum - 计算
need = sum - K,在哈希表中查找need出现的次数,累加到结果 - 将当前
sum存入哈希表(次数 +1) - 关键初始化:
map[0] = 1,处理从数组开头就满足条件的子数组
3 C++ 完整 AC 代码
| |
4 复杂度分析
- 时间复杂度:$O(n)$,一次遍历
- 空间复杂度:$O(n)$,哈希表最坏存 n 个不同前缀和
5 精简优化版(不开前缀和数组,一次遍历)
原代码先构造完整
preSum数组再遍历,多了一次 $O(n)$ 的预处理。改为一边累加一边查哈希表,只扫一遍。
| |
6 同类题型总结(前缀和 + 哈希通用套路)
| 题目 | 转化条件 | 哈希表记录 |
|---|---|---|
| LeetCode 560 和为 K 的子数组 | pre[r] - pre[l] = K | 前缀和 → 出现次数 |
| LeetCode 525 连续数组 | pre[r] = pre[l](0→-1, 1→1) | 前缀和 → 首次下标 |
| LeetCode 974 和可被 K 整除 | 同余前缀和配对 | 余数 → 出现次数 |
通用套路:前缀和做差转化区间条件 → 哈希表快速查找 → 根据题目要求决定存次数还是存下标。
7 易错提醒
valToCount[0] = 1不能漏:当sum == k时,need = 0,此时应计为一种合法方案。- 先查哈希表再更新:避免
k = 0时当前前缀和自己匹配(空子数组不算)。