4.1-1
所有元素都是负数时,最大子数组的和就是A中最大的元素。所有程序会返回A中最大的数。
4.1-2
两个for循环嵌套,且最大迭代次数是n,时间复杂度是 Θ ( n 2 ) \Theta(n^2) Θ(n2)
def find_maximum_subarray(a):
n=len(a)
max_sum=-float('inf')
low=0;high=0
for i in range(n):
sum_da=0
for j in range(i,n):
sum_da+=a[j]
if sum_da>max_sum:
max_sum=sum_da
low=i
high=j
return low,high,max_sum
if __name__ == '__main__':
a=[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]
l,h,ma=find_maximum_subarray(a)
print('最大子数组范围',[l,h]) # python里列表下标从0开始
print('最大和为:',ma)
4.1-3
在我的笔记本电脑上, n 0 n_0 n0是35.混合的方法交叉点会好一些。
4.1-4
计算完成后,若得出的最大子数组的和小于0,返回空数组即可。
4.1-5
没有按照题目中所说的方法,思想是:如果某一段序列A[i…j]的和求出来是小于0的,那么包含这一段的新序列B[m,…i…j…n]肯定比不包含它要小,如果A在B的端点处,那么B可以直接舍弃A。每个元素操作一次,复杂度为 Θ ( n ) \Theta(n) Θ(n)
def find_maximum_subarray(a):
n=len(a)
max_sum=-float('inf')
sum_a=-float('inf')
c_high=0;c_low=0
low=0;high=0
for j in range(n):
c_high=j
if sum_a>0:
sum_a+=a[j]
else:
c_low=j
sum_a=a[j]
if sum_a>max_sum:
max_sum=sum_a
low=c_low
high=c_high
return low,high,max_sum
if __name__ == '__main__':
a=[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]
l,h,ma=find_maximum_subarray(a)
print('最大子数组范围',[l,h]) # python里列表下标从0开始
print('最大和为:',ma)
有一种更一般的求最大子序和的问题是规定子序的长度不能超过M,对于这个问题上面的做法就不适用了,更通用的方法是“前缀和+单调队列”的方法来做。
前缀和:若已知A[1,2,…n],可以计算出其前缀和S[1,…n],其中:
S [ i ] = A [ 1 ] + A [ 2 ] + . . . + A [ i ] S[i]=A[1]+A[2]+...+A[i] S[i]=A[1]+A[2]+...+A[i]
那么A[i,…j]这一段的子序和就等于S[j]-S[i-1].
单调队列:即队列中存储的序列是单调的,那么在取出其中的最值时只需要O(1)的操作。
def find_maximun_subarray(matrix,m):
n=len(matrix)
s = [0 for _ in range(n + 1)]
q = [0 for _ in range(n + 1)]
#求前缀和
for i in range(n):
s[i + 1] = s[i] + matrix[i]
# print(s)
ans = -float('inf')
l = 0;
r = 0 # 队列的左右端点
for i in range(1, n + 1):
if i - q[l] > m:
l += 1
ans = max(ans, s[i] - s[q[l]])
# print('i=',i,'q=',q,'q[l]=',q[l],'ans=',ans,'q[r]= ',q[r],'l=',l,'r=',r)
while l <= r and s[q[r]] >= s[i]:
r -= 1
r = r + 1
q[r] = i
return ans
if __name__ == '__main__':
m=5 # 最大子序长度,
a = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
ans=find_maximun_subarray(a,m)
print(ans)
其中m是规定的最大子序长度,当 m > = A . l e n g t h m>=A.length m>=A.length时,就是书中例题的样子了。