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;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值