在一个数列中找出最大和的连续子列

算法分别是复杂度n^2的蛮力算法,复杂度为n*log(n)的递归算法,上述两者的混合算法,以及复杂度为n的递推算法。最后一个算法我找到的参考答案用了两个循环,而我的算法只使用了一个循环吐舌头

# -*- coding: utf-8 -*-
import time
def findmaximumsubarraybrute(l):
    maximumsum = l[0]
    low = 0
    high = 0
    for i in range(0, len(l)):
        currentsum = 0
        for j in range(i, len(l)):
            currentsum += l[j]
            if currentsum > maximumsum:
                maximumsum = currentsum
                low = i
                high = j
    return maximumsum, low, high

def findmaximumsubarrayrecursive(l):
    def findmaximumsubarrayrecursivemask(l, low, high):
        if low >= high:
            return l[low], low, high
        else:
            mid = (low + high)/2
            leftfinding = findmaximumsubarrayrecursivemask(l, low, mid)
            crossingfinding = findcrossingsubarray(l, low, mid, high)
            rightfinding = findmaximumsubarrayrecursivemask(l, mid+1, high)
            if leftfinding[0] > crossingfinding[0] and leftfinding[0] > rightfinding[0]:
                return leftfinding
            elif rightfinding[0] > crossingfinding[0] and rightfinding[0] > leftfinding[0]:
                return rightfinding
            else:
                return crossingfinding

    def findcrossingsubarray(l, low, mid, high):
        leftsum = l[mid]
        leftmaxsum = leftsum
        leftlow = mid
        for i in reversed(range(low, mid)):
            leftsum += l[i]
            if leftsum > leftmaxsum:
                leftmaxsum = leftsum
                leftlow = i
        rightsum = l[mid+1]
        rightmaxsum = rightsum
        righthigh = mid+1
        for j in range(mid+2, high+1):
            rightsum += l[j]
            if rightsum > rightmaxsum:
                rightmaxsum = rightsum
                righthigh = j
        return leftmaxsum+rightmaxsum, leftlow, righthigh

    return findmaximumsubarrayrecursivemask(l, 0, len(l)-1)

def findmaximumsubarrayrecursiveandbrutalmix(l):
    def findmaximumsubarrayrecursivemask(l, low, high):
        if (high - low) <= 50:
            maximumsum = l[low]
            lowindex = low
            highindex = low
            for i in range(low, high+1):
                currentsum = 0
                for j in range(i, high+1):
                    currentsum += l[j]
                    if currentsum > maximumsum:
                        maximumsum = currentsum
                        lowindex = i
                        highindex = j
            return maximumsum, lowindex, highindex
        else:
            mid = (low + high)/2
            leftfinding = findmaximumsubarrayrecursivemask(l, low, mid)
            crossingfinding = findcrossingsubarray(l, low, mid, high)
            rightfinding = findmaximumsubarrayrecursivemask(l, mid+1, high)
            if leftfinding[0] > crossingfinding[0] and leftfinding[0] > rightfinding[0]:
                return leftfinding
            elif rightfinding[0] > crossingfinding[0] and rightfinding[0] > leftfinding[0]:
                return rightfinding
            else:
                return crossingfinding

    def findcrossingsubarray(l, low, mid, high):
        leftsum = l[mid]
        leftmaxsum = leftsum
        leftlow = mid
        for i in reversed(range(low, mid)):
            leftsum += l[i]
            if leftsum > leftmaxsum:
                leftmaxsum = leftsum
                leftlow = i
        rightsum = l[mid+1]
        rightmaxsum = rightsum
        righthigh = mid+1
        for j in range(mid+2, high+1):
            rightsum += l[j]
            if rightsum > rightmaxsum:
                rightmaxsum = rightsum
                righthigh = j
        return leftmaxsum+rightmaxsum, leftlow, righthigh

    return findmaximumsubarrayrecursivemask(l, 0, len(l)-1)

def findmaximumsubarraynonrecursive(l):
    maximumsum = l[0]
    low = 0
    high = 0
    maximumcross = l[0]
    cross = 0
    for i in range(1, len(l)):
        if (l[i]-maximumcross) > 0 and maximumcross < 0:
            cross = i
            maximumcross = l[i]
        else:
            maximumcross += l[i]
        if maximumsum < maximumcross:
            low = cross
            high = i
            maximumsum = maximumcross
    return maximumsum, low, high

l = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
l = range(1, 10001)
#l = [-2, -4, -3, -1, -7]

start = time.clock()
print findmaximumsubarraybrute(l)
end = time.clock()
print end - start

start = time.clock()
print findmaximumsubarrayrecursive(l)
end = time.clock()
print end - start

start = time.clock()
print findmaximumsubarrayrecursiveandbrutalmix(l)
end = time.clock()
print end - start

start = time.clock()
print findmaximumsubarraynonrecursive(l)
end = time.clock()
print end - start


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值