最大子段和问题分析


问题:

  给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整均为负数时定义子段和为0,依此定义,所求的最优值为:
 
    Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n
    例如,当(a1,a2,a3,a4,a4,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为20。


 

此问题最常见,也是最容易想到的办法:

 

 

对这种三层循环的解法进行初步的优化,因为数列和具有如下性质:

 

S[i] = S[i-1]+a[i];

 

再对上面的算法进行如下优化:

 

1.空间优化,由于没有必要把所有的子段和保存下来,因为直接用一个变量sum保存最大子段和便可

2.时间优化,由于S[i] = S[i-1]+a[i]因此不需要把所有的S求出来

 

代码如下:

 

 

以上已经是属于o(n^2)中最优的算法了,但对于1W+级的数据,处理速度仍然太慢。

 

于是思考以分治法:

 

1.把整个段分成两部分,m = (left+right)/2

 

2.最大子段和要么属于左边部分,要么属于右边部分,要么属于包含a[m],a[m+1]的某个中间部分

 

3.对于属于左右两部分的,可以递归求出,重点是处理中间部分。

 

4.由于中间部分必然包含a[m],a[m+1]。因此把a[m]~a[0]倒过来求和,最大者即为左边必然包括a[m]的最大子段和lmax,同理可得右边rmax,所以lmax+rmax必然是包含a[m],a[m+1]的最大子段和。

 

5.以上三者,返回其较大值

 

代码如下:

 

 

 

再思考这个问题,实际上是典型的子结构问题,可以使用动态规划来解。

定义b[i]为 子段结束位置为 i 时的最大子段和,那么当b[i-1]>0时,b[i] = b[i-1]+a[i]否则b[i] = a[i]

 

最后,数组b[i]中最大值必然为最大子段和 :

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值