最大子序列问题的动态规划解法(leetcode 53题)Kadane算法

有一点背景:Kadane的算法是基于将一组可能的解决方案分解为互斥(不相交)集合。 我们利用任何解决方案(即解决方案组中的任何一个成员)将始终具有最后一个元素i(这就是“在位置i结束的和”)的事实。
因此,我们只需要检查,一个一个的一整套解决方案,其最后一个元素的索引是1,一整套的解决方案,其最后一个元素的索引是2,然后是3,依此类推到n。 事实证明,这个过程可以在线性时间内进行。
Kadane的算法从一个简单的归纳问题开始:如果我们知道在位置i处结束的最大子数组总和(称为B{i}),那么在位置i + 1处结束的最大子数组总和是多少(相当于,B{i+1}是什么)? 答案结果相对简单:在位置i + 1处结束的最大子数组总和包括以位置i结尾的最大子数组总和作为前缀,或者不包括(相当于,B{i + 1} = max(A{i + 1},A{i + 1} + B{i}),其中A{i + 1}是位置i+1处的元素)。
因此,我们可以通过在数组上迭代一次来计算所有位置i结束于位置i的最大子数组总和。 当我们迭代时,我们只是跟踪我们所见过的最大的总和。 因此,这个问题可以用下面的代码来解决:
python:

def max_subarray(A):
2     max_ending_here = max_so_far = A[0]
3     for x in A[1:]:
4         max_ending_here = max(x, max_ending_here + x)
5         max_so_far = max(max_so_far, max_ending_here)
6     return max_so_far

注意:用一点推理,你会看到max_so_far等于max(B{0},B{1},B{2},...,B{i})。该算法也可以很容易地修改,以跟踪最大子阵列(当max_so_far改变时)的开始和结束位置,以及我们想要的情况下 如果所有元素都是负数,则允许零长度的子数组(隐式总和为0)。

由于这种算法使用最佳子结构的方式(每个位置处的最大子阵列以相关但较小且重叠的子问题以最简单的方式计算:最大子阵列结束于前一个位置),该算法可以被看作简单/ 动态规划的一个小例子。

Kadane算法的运行时复杂度是O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值