leetcode刷题:53.最大子数组和

题目地址:53.最大子数组和

这是非常经典的动态规划题目。如何去寻找这个子数组和呢?我们可先从数学上的逻辑进行分析:

由于是连续序列,所以每个子数组的和都是从左边往右边相加得到的。很多人在看到这道题时第一想法肯定是暴力求解,即求出所有子数组的和并进行比较,这样时间消耗未免太大。

我们可以将上述过程拆分一下,假设pre(i)表示以下标为i的元素结尾的连续最大子数组和(并未规定子数组的起始位置,仅关心结束为止)。那么pre(i)的取值情况有两种:

  1. 在这个子数组中,如果i之前的子数组的最大子数组和(即pre(i-1))加上i处的值以后,比nums[i]本身的值要小(即pre(i-1)为负数),那么nums[i]就是当前状态下的最大子数组和;
  2. 如果i之前的子数组的最大子数组和(即pre(i-1))加上i处的值以后,比nums[i]本身的值要大(即pre(i-1)为正数),那么nums[i]+pre(i-1)即是当前状态下的最大子数组和;

所以我们可以写出以i结尾的最大子数组和的表达式:

pre(i)=max(pre(i-1)+nums[i], nums[i])

按照如上关系就可以求出每一个i所对应的最大子数组和,它们构成了一个集合。整个数组的最大子数组和就是这个集合中的最大值,记为ret。

以下是代码部分:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int ret=nums[0];
        int pre=0;
        for(auto& x:nums)
        {
            pre=max(pre+x,x);
            ret=max(ret,pre);
        }
        return ret;
    }
};

猜你喜欢

转载自blog.csdn.net/fbzhl/article/details/134661402