题目
https://leetcode.com/problems/maximum-subarray/
思路
这道题可以说是我这两天见过的最有趣的题了,表面上看起来非常简单,只有一脚踩进去才知道里面深千尺。最开始我完全找不到思路,于是开始看答案,第一眼看到的是这个:
看得心如死灰。
尝试了一下写遍历:
1 | class Solution: |
很显然这种东西怎么可能过得了…复杂度应该是O(n^2)
然后我找到了个魔法般的Kadane’s algorithm:https://www.youtube.com/watch?v=2MmGzdiKR9Y
这个视频很方便又简单地让我理解了动态规划在这道题的应用,代码如下 :
1 | class Solution: |
这个视频最精髓的一部分我感觉应该在这里:
以当前位置为X,过去的状态为M,比对X+M与X之间的大小。这里作者还举例了,假设存在一个更大区间并且覆盖M范围的T,T与X比对,当T+X小于M+X的时候,则必然sum[M]大于sum[T]。
而视频最后直接使用例子来描述动态规划的本质:计算每个数值时候时候让计算结果能够保存在当前位置下的状态,例如max_current = max(num,max_current+num),然后这些状态可以被利用起来计算之后的状态。
然后最后我看到了一个神来一手:
1 | for i in range(1, len(nums)): |
作者的原话是:
本质上和Kadane’s algorithm原理是一致的,同样是不断动态获取局部的最优解。但是简洁到让人难以想象。