前缀和专题实战
29. 和为 K 的子数组
题目链接: 560. 和为 K 的子数组 - LeetCode
题目描述
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

示例
输入:nums = [1,1,1], k = 2 输出:2 解释:[1,1] 在索引 0-1 和 1-2 处各出现一次。

解题思路
这道题的核心在于利用前缀和配合哈希表来优化查找效率。
想象一下,如果我们定义 sum[i] 为从下标 0 到 i 的所有元素之和。那么,任意区间 [x, i] 的和就可以表示为 sum[i] - sum[x-1]。
我们的目标是找到有多少个起始位置 x,使得 sum[i] - sum[x-1] == k。移项后得到:
sum[x-1] == sum[i] - k
这意味着,当我们遍历到当前位置 i 时,只需要知道在 i 之前有多少个前缀和等于 当前前缀和 - k,就能确定以 i 结尾的满足条件的子数组数量。
为了高效查询,我们不需要维护一个完整的前缀和数组,而是用一个哈希表(unordered_map)记录每个前缀和出现的次数。一边计算当前前缀和,一边更新哈希表。
注意初始化 hash[0] = 1,这代表前缀和为 0 的情况出现了 1 次(即空数组),用于处理从数组开头就满足条件的情况。
代码实现
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> hash;
hash[0] = 1; // 初始状态,前缀和为 0 出现 1 次
int n = nums.size();
int sum = , ret = ;
( x : nums) {
sum += x;
(hash.(sum - k)) {
ret += hash[sum - k];
}
hash[sum]++;
}
ret;
}
};




