最大子序和题解

链接

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int max = nums[0];
        int tmpSum = 0;
        int index = 0;
        while (max < 0) {
            while (index < nums.size()) {
                if (nums[index] > max) {
                    max = nums[index];
                    break;
                }
                index += 1;
            }
            if (index >= nums.size()) break;
        }
        for (int i = index; i < nums.size(); ) {
            for (index = i; index < nums.size(); index++){
                tmpSum += nums[index];
                if (tmpSum < 0) {
                    i = index + 1;
                    tmpSum = 0;
                    break;
                } else if (tmpSum > max) {
                    max = tmpSum;
                }
                if (index == nums.size() - 1) {
                    return max;
                }
            }
        }
        return max;
    }
};

思路

遍历数组,找到第一个大于0的数;
累加该数之后的值,如果小于零,从下一个数开始重新累加;如果大于最大值,则赋值;如果是其他,继续累加;
累加到数组的最后一个元素结束;

分析

上述过程一定能找到最大值:
首先,全数组小于零的情况先处理;(必只有一个元素组成最大值)
假设数组至少有一个正数,必能找到第一个正数;
在部分和恒正的一段数组上,用上述方法寻找最大值,若有其中一段的和最大且不为我们的结果,由我们的寻找方法,前面部分和恒正,从而添加上前面的一段,必然更大,从而矛盾;
若出现部分和负数,则最大值必然断开在多段中,只要找到其中的最大段即可;

要点

两重while循环先处理数组全负或找到第一个正数的情况;
局部变量i不会达到终止条件,若index遍历到数组尾部,直接返回结果;


动态规划降维打击
用 f(i) 代表以第 i 个数结尾的「连续子数组的最大和」
则f(i)为f(i-1) + nums[i],nums[i]中的最大值,选其中的最大值即可;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值