leetcode算法总结 —— 前缀和

文章目录


https://leetcode-cn.com/problems/subarray-sum-equals-k/solution/de-liao-yi-wen-jiang-qian-zhui-he-an-pai-yhyf/
图形参照上图,公式不用上面的上面的有错位。

思路

我们求数列的和时,Sn = a1+a2+a3+…an; 此时Sn就是数列的前 n 项和。
例 S5 = a1 + a2 + a3 + a4 + a5; S2 = a1 + a2。所以我们完全可以通过 S5-S2 得到 a3+a4+a5 的值,

创建一个数组保存前N项和,前缀和数组preSum,这样我们可以快速得到某个区间的和。
比如我们要得到num[2]到num[4]之前的和,那么我们可以使用preSum[4]-preSum[1]
然后我们使用map来找每个值前面的值

模板

560题举例

    int subarraySum(vector<int>& nums, int k) {
    
    
        int count = 0;
        //创建前缀和数组
        vector<int> preSum(nums.size());
        preSum[0] = nums[0];
        for (int i = 1; i < nums.size(); i++) {
    
    
            preSum[i] = nums[i] + preSum[i-1];
        }
        //得到前缀和数组之后,我们要求的题目就很简单了,就是前缀数组中两个数的差是否为K。其实就是两数之和的思路,但是这里map存储的是前缀和和出现的次数
        map<int,int> m; //存前缀数组元素和对应出现的次数
        m[0]++;//添加一个0,因为某个前缀和和0也能组成一个
        //遍历前缀数组,如果当前数
        for(int i = 0; i < preSum.size(); i++) {
    
    
            int target = preSum[i] - k;
            //如果在map中找到了该数,则
            if(m.find(target) != m.end()) {
    
    
                count += m[target];
            }
            //不管找没找到都次数加一
            m[preSum[i]]++;
        }
        return count;
    }
    1. 寻找数组的中心下标
    1. 和为K的子数组(map存储<前缀和,出现次数>)
    1. 和相同的二元子数组(同560)
    1. 和可被 K 整除的子数组(注意取余数方式和map存储的值)

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/115143934
今日推荐