算法与数据结构(和为K的子数组)
题目
思路
前缀和+哈希表
这里引入了一个前缀和的概念。什么是前缀和呢?对于数组中的任意位置i,前缀和sum[i]为从第一个元素到第i个元素的元素和。这说明你要是想求第i+1到第j的子数组和,可以用sum[j]-sum[i]来计算。
我们可以用哈希表来存储每个位置的前缀和以及它出现的次数。
关键点说明
sum-k的意义:如果在hashmap中找到了sum-k,则说明在之前某个点的累计和为sum-k,而当前点的累积和是sum,则说明之前的点到当前点的子数组之和恰好为k =sum-(sum-k)。
如何去利用这个条件呢?
如果sum-k在哈希表中,则sum-k出现的次数为从不同起点到当前节点子数组和为k的不同情况。每个sum-k都对应一个起点,使得从那个起点到当前节点的和为k。
因此,每当我们找到一个 sum - k 存在于哈希表中时,我们就把它的计数(即之前这种情况发生的次数)加到 count 上,这表示我们又找到了相应数量的以当前元素结束的子数组,其和为 k。
为什么要定义hashmap[0]=1,如果sum-k等于0,说明存在子数组的和等于k,直接给次数+1即可。
代码
class Solution {
public:
int subarraySum(vector<int>& nums, int k)
{
unordered_map<int,int> hashmap;
int sum=0,count=0;
hashmap[0] = 1;
for(int i=0;i<nums.size();i++)
{
sum += nums[i];
if(hashmap.find(sum-k) != hashmap.end())
{
count += hashmap[sum-k];
}
hashmap[sum]++;
}
return count;
}
};