码迷,mamicode.com
首页 > 编程语言 > 详细

最大连续子数组算法学习

时间:2016-06-12 18:15:23      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

作为零基础学习的弱智艰难的入行后,在黑暗中摸爬滚打中过了几个月,才想起应该开个博客记录下自己的学习历程和整理知识点。刚刚接触算法的我,博客就以记录我的算法学习历程为开端吧。多说无益,下面开始:

如果已知后三十天的股票涨跌停的情况,那么我该如何确定自己收益的最大值是多少呢?这里可以将股票每天的变化存进一个数组里,涨记为正,跌记为负,那么最后这个实际问题就转化为了求最大连续子数组的问题了,即我怎么切割这个数组使得这个数组里的值最大?这里简单的用了分治法去计算,首先将data分成2份,一份为左data,一份为右data,那么就可以通过循环求出左右data各自的最大值,先求左边数组(以下为python代码)

    #left array
    mid = len(data)/2
    ssum = 0
    sumLeft = 0
    leftData = data[:mid]
    leftIndex = 0
    for i in range(len(leftData)-1,-1,-1):
        ssum = ssum + leftData[i]
        if ssum > sumLeft:
            sumLeft = ssum
            leftIndex = i

mid为data的中点,用mid把data分成2份,左边数组为leftData,利用ssum计算左数组中的累加值,leftData存累加的最大值。如果累加值大于了最大值,那么就把这个累加值存为最大值。右边数组同理

    #right array
    sumRight = 0
    ssum = 0
    rightData = data[mid:]
    rightIndex = 0
    for j in range(len(rightData)):
        ssum = ssum +rightData[j]
        if ssum > sumRight:
            sumRight = ssum
            rightIndex = j

这样就能算出左右2边的最大连续子数组啦,是不是相互比较之后返回较大那个就Ok了呢?没有,原来忽略了一个,就是假如这个最大子数组跨过了中点mid呢?我们还得把这个数组的最大子数组取出来一起比较:

    crossData = data[leftIndex:rightIndex + mid + 1]
    sumCross = 0
    ssum = 0
    crossIndex = 0
    for x in range(len(crossData)):
        ssum = ssum + crossData[x]
        if ssum > sumCross:
            sumCross = ssum
            crossIndex = x

之前用i,j 分别记录了左数组的最大值索引i,和右数组的最大值索引j,那么可以想到这个cross数组必然在i,j这2个边界内,因为这2个已经是2边的最大值了,如果再加超出边界部分的值一定是小于最大值的。

所以可以把data切割为crossData,这里要注意j因为是右边数组,所以j在整个data中应该还需要加上中点的值才能真正获取到crossData的右边界,因为切割的时候不包含最后的j,为了把右边界算进去,还必须加上1

之后按照之前的套路,求出crossData的最大值 sumCross

好了,接下来这3个值进行比较返回最大的就可以了

maxSum = max(sumRight,sumLeft,sumCross)

由于刚学,算法还有很多可以改进的地方,只能一步一步来了。

 

最大连续子数组算法学习

标签:

原文地址:http://www.cnblogs.com/goddessofpom/p/5578396.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!