随笔 - 112  文章 - 0  评论 - 0  阅读 - 1383

最大子数组和(动态规划)

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

思路: 动态规划

我们用 f(i) 代表以第 i 个数结尾的「连续子数组的最大和」,那么很显然我们要求的答案就是:max{f(i)} (0<i<n)

因此我们只需要求出每个位置的 f(i),然后返回 f 数组中的最大值即可。那么我们如何求 f(i) 呢?我们可以考虑 nums[i] 单独成为一段还是加入 f(i−1) 对应的那一段,这取决于 nums[i] 和 f(i−1)+nums[i] 的大小,我们希望获得一个比较大的,于是可以写出这样的动态规划转移方程:

f(i)=max{f(i−1)+nums[i],nums[i]}

 

复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        //动态规划
        int n = nums.size();
        vector<int> dp(n,0);
        dp[0] = nums[0];
        int maxValue = dp[0];
        for(int i=1;i<n;i++){
            dp[i] = max(dp[i-1]+nums[i],nums[i]);
            if(dp[i]>maxValue) maxValue = dp[i];
        }
        return maxValue;
    }
};
复制代码

 方法二:前缀和+最小前缀和

复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        //前缀和
        int n = nums.size();
        int pre_sum=0,min_pre_sum=0;
        int ans=INT_MIN;
        for(int i=0;i<n;i++){
            pre_sum +=nums[i];
            ans = max(ans,pre_sum-min_pre_sum);
            min_pre_sum = min(min_pre_sum,pre_sum);
        }
        return ans;
    }
};
复制代码

 

posted on   _月生  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示