文章目录
-
-
- [1. 和为K的子数组🆗](#1. 和为K的子数组🆗)
-
1. 和为K的子数组🆗
- 🐧解题思路: 前缀和 + 哈希表
🍎 设i
为数组中的任意位置,⽤ sum[i]
表⽰ [0, i]
区间内所有元素的和。
🍎 想知道有多少个「以 i 为结尾的和为 k 的⼦数组」,就要找到有多少个起始位置为 x1, x2, x3...
使得 [x, i]
区间内的所有元素的和为 k 。那么[0, x]
区间内的和是不是就是sum[i] - k
了。
于是问题就变成:
找到在[0, i - 1]
区间内,有多少前缀和等于sum[i] - k
的即可。
我们不⽤真的初始化⼀个前缀和数组,因为我们只关⼼在i
位置之前,有多少个前缀和等于
sum[i] - k
。因此,我们仅需⽤⼀个哈希表,⼀边求当前位置的前缀和,⼀边存下之前每⼀种
前缀和出现的次数。
cpp
class Solution
{
public:
int subarraySum(vector<int>& nums, int k)
{
unordered_map<int, int> hash; // 统计前缀和出现的次数
// 为什么初始值 hash[0] = 1呢?
// 因为:有可能 sum == k, 我们统计 hash.count(sum - k)统计的是当前元素之前的值,没有统计千
// 前缀和刚好等于 k 的情况
hash[0] = 1;
int sum = 0, ret = 0;
for(auto x : nums)
{
sum += x; // 计算当前位置的前缀和
if(hash.count(sum - k)) ret += hash[sum - k]; // 统计个数
hash[sum]++;
}
return ret;
}
};