Leetcode刷题记录--53. 最大子序和

小菜鸟第一次接触动态规划,请多包涵~
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

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

在这个问题中,我们将求解最大和连续子数组分解为求解到当前值的最大连续子序列,而这个最大子序列的求解也是和先前的子序列相关的,我们用maxnum存放子序列,举例如下:
nums[0]对应的子序列为[-2],最大子序列为[-2]
nums[1]对应的子序列为[-2,1][1],最大子序列为[1]
nums[2]对应的子序列为[-2,1,-3][1,-3][-3],最大子序列为[1,-3]
以此类推····
它们的规律都是比较maxnum[i-1]+nums[i]和nums[i]之间的大小关系
但这还不够,我们还需要一个概念才能帮助我们判断出什么才是maxnum[i]的值,观察上面两个式子(maxnum[i-1]+nums[i]和nums[i]),我们可以发现,什么时候maxnum[i-1]+nums[i]会大于nums[i],那就是当maxnum[i-1]>0的时候,因为我们可以知道,假若maxnum[i-1]的值小于0,不管nums[i]本身是否大于0,它一定会使得得到的最大连续子序列的值更小
因此我们可以得到下列转移方程

\[maxnum[i]= \begin{cases} nums[i]& maxnum[i-1]<0\\ maxnum[i-1]+nums[i]& maxnum[i-1]>=0 \end{cases}\]

同时,我们在求得maxnum数组的时候再用一个变量随时更新最大值即可

具体代码如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if (nums.size() == 0){
            return 0;
        }

        int max = nums[0];
        vector<int> maxnum(nums.size());
        maxnum[0] = nums[0];
        //每一位都是到当前位置的最大子序和,而每一个最大子序和都和上一位相关
        for(int i = 0; i < nums.size()-1; i++){
            if(maxnum[i] >= 0){
                maxnum[i+1] = maxnum[i]+nums[i+1];
            }else{
                maxnum[i+1] = nums[i+1];
            }

            if (max < maxnum[i+1]){
                max = maxnum[i+1];
            }
        }
       
        return max;
    }
};

参考来源:

https://leetcode-cn.com/problems/maximum-subarray/solution/zheng-li-yi-xia-kan-de-dong-de-da-an-by-lizhiqiang/

posted @ 2020-05-09 08:25  c_y_yuan  阅读(113)  评论(0编辑  收藏  举报