[leetcode]Maximum subarray

Maximum subarray是一个很常见的DP问题,碰见好几次了,每次都想不起来是怎么做的,写下来加深印象。

问题:

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.

题目就是说在一个给定数组里,找到最大连续子数组的和,并不需要制定子数组在哪,只要返回正确的和就行了。

解法:

给定一个数组A[],设两个max值,max_so_far=A[0]和max_ending_here=0。

For each element in array

max_ending_here=max_ending_here+A[i]

if(max_so_far<max_ending_here)

max_so_far=max_ending_here

if(max_ending_here<0)

max_ending_here=0

end for

return max_so_far

难懂的地方就是两个max之间的逻辑:

max_ending_here和max_so_far的区别就在于在处理A[i]的时候,max_ending_here代表以A[i]结尾的数组的最大值,那么它未必是在A[0]~A[i]之间的最优解,而max_so_far才是最优解,这个max_so_far未必是以A[i]为结尾的,可能是0和i之间的某一段,但是当max_ending_here大于max_so_far,我们就要更新它。


但是每个max_so_far其实都是由max_ending_here来的,max_ending_here是如何维护的呢?

max_ending_here顾名思义,这个数组必须ending here所以我们不用管这个数组的末尾,只需要维护好数组的开头。它维护数组的开头也很简单,一般情况我们都不去更新这个开头(不论中间是否有负数,有几个负数),但是,一旦max_ending_here小于0了,也就代表这中间出了一个或几个“害群之马”,它们使得前面的和都显得很无力,此时我们就要更新这个开头了,从下一个作为开头,这时候max_ending_here变成了0,但是之前那个最大子数列已经被记录在max_so_far里面了,可以放心的去后面的array里再找max。


有一点需要注意,两个if的位置不能换,否则如果max_so_far压根就小于0,max_so_far会被更新为0(而这是不对的,max_ending_here更新为0只是为了之后计算方便,而并不是真的max_ending_here为0)。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值