算法分别是复杂度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