题目:
给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大。
例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4]
,
连续子序列 [4,-1,2,1]
的和最大,为 6
。
思路1:贪心法【时间复杂度为O(n2)】
设置两个最大标记:subSum = max( 当前值,之前的序列+当前值 )
maxSum = max( 当前最大和,subSum 【更新的和】)
def maxSub (A): if not A: return 0 else: subSum=maxSum=A[0]for item in A[1:]: subSum=max(item,item+subSum) maxSum=max(subSum,maxSum) return maxSum
思路2:分治法【时间复杂度为O(nlogn)】
分:左、中、右
治:左【不处理】、右【不处理】、中【中间数往左遍历相加和取最大,中间数往右遍历相加和取最大,再加总左右两边】
并:比较左、中、右大小,取最大。
比如:nums=[-2,1,-3,4,-1,2,1,-5,4]
一:左:【-2,1,-3,4,-1】右:【2,1,-5,4】,中间数为-1,故【中】从-1开始往左往右遍历相加和
二:先递归左【-2,1,-3,4,-1】,左:【-2,1,-3】,右:【4,-1】,中:-3
三:再递归左【-2,1,-3】,左:【-2,1】,右:【-3】,中:1
四:再递归左【-2,1】,左【-2】,右:【1】,中:-2
由于左【-2<0】,return 0,
右【1>0】 return 1(右的值)。
中:-2向左遍历和为-2,向右遍历(不含中-2)和为1,两者相加为-1,return -1
比较左、中、右大小,最大为右,故【-2,1】return 1【右值】
五:(返回到第三) 左【-2,1】返回值为1
右【-3】返回值为-3
中:1往左遍历和最大为1,往右为-3,故两者相加为-2
比较左、中、右,故【-2,1,-3】return 1
六:(返回二)左:【-2,1,-3】return 1,右【4,-1】return 4。中【-3】,往左遍历,最大应该是-3+1=-2,往右遍历:4,return -2+4=2。比较大小,【-2,1,-3,4,-1】return 4。
七:(返回一)左【-2,1,-3,4,-1】return 4,右【2,1,-5,4】return 4。中【-1】,左遍历为3,右遍历为3,return 3+3=6。比较大小(4,4,6)return 6。
def MaxSubArray(nums,l,r): if r-l==1: if nums[l]>0: return nums[l] else: return 0 mid=(l+r)//2 maxSum=0
#左 maxLeftSum=MaxSubArray(nums,l,mid)
#右 maxRightSum=MaxSubArray(nums,mid,r)
#中 MLA=0 MRA=0 maxMLA=0 maxMRA=0
#中往左遍历 i=mid while i>=l: MLA+=nums[i] if MLA>maxMLA: maxMLA=MLA i-=1
#中往右遍历 j=mid+1 while j<r: MRA+=nums[j] if MRA>maxMRA: maxMRA=MRA j+=1
#比较左中右大小 return max(maxLeftSum,maxRightSum,maxMLA+maxMRA)