LeetCode.560. 和为 K 的子数组

69 阅读1分钟

题目

image.png

思路

  • 前缀和
    对于 1 2 3 , k = 5
    可以计算以每个数结尾的前缀和为: 1 3 6
    对于每个位置i,期望找到它左边的前缀和是 k - a[i]
    比如,对于最后一个元素3,此位置的前缀和 = 6
    如果他左边存在一个前缀和 = 1,就好了,因为这样的话,相当于就是左边有一段子串和 = 1
    又因为当前位置的前缀和 = 6,这说明在左边这段子串和 = 1的这段子串,和当前元素的中间,隔了一段和为 6-1=5 的子串 = k
    我们期望的子串和是k,若此时左边有一段和为 当前前缀和-k的子串,意味着,左边这段到当前为止之间的这段子串和 = k
  • 因为是计算子串的数量,所以可以用计数数组,或者map,每次更新前缀和,就记录该前缀和出现的次数 image.png

代码

int subarraySum(vector<int>& a, int k) 
{
    int n = a.size();
    int presum = 0;
    int ans = 0;
    map<int,int> mp;
    mp[0] = 1;//特殊的边界是 某个元素正好就是目标k,那么对于这个元素来说,它距离目标k还需要一个0,所以0也要作为一个前缀和
    for(const auto& cur:a)
    {
        presum = presum + cur;
        if(mp.contains(presum - k))
        {
            ans += mp[presum-k];
        }
        mp[presum]++;
    }
    return ans;
}