[560. 和为 K 的子数组 && 53. 最大子数组和] 前缀和问题

文章讨论了解决560.和为K的子数组和53.最大子数组问题的高效方法,利用前缀和和滑动窗口技巧降低时间复杂度,通过数学转化简化计算过程。
摘要由CSDN通过智能技术生成

Problem: 560. 和为 K 的子数组

Problem: 53. 最大子数组和

文章目录

思路

对于一个序列求解问题,我们可以先从两个维度思考:要不要排序,是否求解连续子序列
这两道题都是求连续子序列问题。对于这一类拥有连续性质问题,滑动窗口前缀和等方法往往可以进行时间上的优化。

解题方法

前缀和则可以将最内层遍历转换为简单的做差,这样做的好处不仅在于可以降低 n 的时间复杂度,还在于可以列出子序列和的计算公式,如此可以通过数学的方式进行三个值的相互求解。

例如对 [560. 和为 K 的子数组],此时的目标值——子序列和已经给出为k,需要寻找目标子序列。我们便可以移项,通过确定的子序列和前缀和搜索子序列,从而求解。
同样的对 [53. 最大子数组和],我们通过前缀和公式,将原本对于子序列和最大值的比较转换为对前缀和最小值的比较,在不进行子序列和计算的前提下预知计算结果的大小关系,从而极大地降低了时间复杂度。

Code

560. 和为 K 的子数组

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int ans = 0;
        int pre = 0;
        unordered_map<int, int> pre_m; // 前缀和为key的个数
        pre_m[0] = 1;

        for(auto& num : nums) {
            pre += num;
            if (pre_m.find(pre - k) != pre_m.end()) {
                ans += pre_m[pre - k];
            }
            pre_m[pre] = pre_m.count(pre) ? pre_m[pre] + 1 : 1;
        }

        return ans;
    }
};

53. 最大子数组和

class Solution {
    const int MIN = -10001;
public:
    int maxSubArray(vector<int>& nums) {
        priority_queue<int, vector<int>, greater<int>> q;
        q.push(0);
        int pre = 0;

        int res = MIN;
        for(int i = 0; i < nums.size(); i++) {
            pre = pre + nums[i];
            res = max(res, pre - q.top());
            q.push(pre);
        }

        return res;
    }
};
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值