算法笔记:前缀和 - 和为 K 的子数组

原题:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

一开始以为是滑动窗口问题,写完提交才发现没考虑负数。。。寄

总之滑动窗口一般只适用于字符串相关的子串问题。子数组的话,得考虑前缀和了

基本思路:(前缀和 + 哈希表)

        1. 首先,前缀和是指:数组从下标0到当前位置所有元素之和

                如:对于 [1,2,3,4,5],其前缀和数组为 [1,3,6,10,15]

        2. 那么,前缀和与子数组有什么关系?仍以 [1,2,3,4,5] 为例:

                比如说我们想求下标 1 到 3 之间的和,即 2 + 3 + 4 = 9

                在前缀和数组中,该值正好为下标 3 与 0 的差,即 10 - 1 = 9

                由此我们可以得出结论:任意子数组的和,均可以通过不同元素的前缀和之差求出

        3. 因此,我们得到如下等式:当前元素前缀和 - 之前求得的某个前缀和 = K

                当数组中存在某个子数组之和为 K 时,上述等式成立

                移项一下:之前求得的某个前缀和 = 当前元素前缀和 - K

                这与经典“两数之和”问题有点类似了:

                        我们采用哈希表:键 - 前缀和,值 - 该前缀和出现的次数

        4. 最终,我们得出关键步骤:

                遍历,计算当前前缀和 sum

                寻找与 sum 之差正好为 K 的其他前缀和:即 find( 当前元素前缀和 - K )

                这样的“其他前缀和”有多少个,最终的答案就增加多少

                最后,将“当前前缀和”也插入哈希表

代码如下:

int subarraySum(vector<int>& nums, int k) {
    int sum = 0;                        //当前的前缀和
    int ans = 0;                        //最终答案
    unordered_map<int, int> pre_sum;    //哈希表
    pre_sum[0] = 1;                     //初始化哈希表(考虑特殊情况:数组的首元素即为K时)
    for (const int& i : nums)
    {
        sum += i                        //更新前缀和
        if (pre_sum.find(sum - k) != pre_sum.end())    //寻找与sum之差为K的其他前缀和
        {
            ans += pre_sum[sum - k];    //这样的每一个“其他前缀和”,都能与sum构成一个答案
        }
        pre_sum[sum]++;                 //更新哈希表
    }
    return ans;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值