请问老师关于 leetcode 53 号求最大子序和的问题

来源:11-1 结语

Osuribaba

2020-12-08

请教老师一个问题,我在做 leetcode 的 最大子序和 这个问题的时候, 一般的动态规划解法是这个

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

状态转移方程是 res[i] = max(res[i - 1] + nums[i], nums[i]), 我有点不太理解,既然求的是 最大的 “连续” 子数组 的话,res[i - 1] 又表示是 0 ~ (i -1) 的最大子序和, 那咋保证 res[i - 1] + nums[i] 就是连续的呢?
比如说有个数组: [-1, 1, 2, 3, -1, 1], 要求 res[5] 的最大连续和, 那 res[4] 的最大和是,中间的 1 + 2 + 3 = 6, 然后 nums[5] 是 1, 按照转移方程就 res[5] = max(res[4] + nums[5], nums[5]), 那答案应该是 7 呀, 但是中间那 1,2,3 和最后一位的 1 它是不连续的呀。我感觉我好像哪块儿绕进去了,求老师指点,谢谢老师~

写回答

1回答

liuyubobobo

2020-12-08

res[i - 1] 表示的不是是 0 ~ (i -1) 的最大子序和;res[i - 1] 表示的是,以 nums[i - 1] 结尾的最大子序和,所以 res[i - 1] 一定包含 nums[i - 1] 这个数。


也正因为如此,在你的代码中,我们还需要另外一个 maxAns 来计算真正的最大子序列和,而不是直接返回 pre(如果是你理解的定义,直接返回 pre 就够了)。


res[i] = max(res[i - 1] + nums[i], nums[i]) 的意思是,以 nums[i] 结尾的最大子序列和,或者是在 res[i - 1] 的基础上,再加上 nums[i],或者以 nums[i] 单起一个新的序列。


你后面举的例子是错误的,因为 res[4] 不可能等于 6。而是等于 5。实际用这个测试用例运行这个程序,试试看?看在每一步,res[i] 具体是多少?


继续加油!:) 

0
1
Osuribaba
好的,了解,谢谢老师
2020-12-08
共1条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程