【方法一】
这道题的简单版本是最大子序和问题,所以本题可以拆分为两个部分来解。
1.含有最大和的子数组未跨越列表头和列表尾- - - >化为最大子序和问题
2.含有最大和的子数组跨越列表头和列表尾 - - - >最小子序和问题,用总和减去最小子序和即所求最大和(原理:例如一环形数组A=[5,-3,-2,3,-1,5],最大和的子数组为[3,-1,5,5],对A取负值:-A=[-5,3,2,-3,1,-5],原来的最大和的子数组变为最小子数组,此时,问题化为求-A的最大和的子数组;同时有下面的关系,子数组的最大和=总和-子数组的最小和 max_sum=total-min_sum)。
class Solution:
def maxSubarraySumCircular(self, A: List[int]) -> int:
def maxSubarraySum(nums):
maxsum=nums[0]
cursum=nums[0]
for i in range(1,len(nums)):
cursum=max(cursum+nums[i],nums[i])
if cursum>maxsum:
maxsum=cursum
return maxsum
if len(A)==0:
return 0
else:
max1=maxSubarraySum(A)
total=sum(A)
max2=maxSubarraySum([-i for i in A])
if -total==max2: #处理当A全是负值的情况
return(max1)
else:
return(max(max1,total+max2))
上面code对全是负值的判断和下面的不同,上面是total=min_sum,下面是max_sum<0,都是可行的,没什么差别。
class Solution:
def maxSubarraySumCircular(self, A: List[int]) -> int:
def maxSubarraySum(nums):
maxsum=nums[0]
cursum=nums[0]
for i in range(1,len(nums)):
cursum=max(cursum+nums[i],nums[i])
if cursum>maxsum:
maxsum=cursum
return maxsum
if len(A)==0:
return 0
else:
total=sum(A)
max1=maxSubarraySum(A)
if max1<0:
return max1
else:
max2=maxSubarraySum([-i for i in A])
return(max(max1,total+max2))
【方法2】
直接在一次遍历中求得当前最大和当前最小,最大和最小,最后判断列表全是负值的情况
class Solution:
def maxSubarraySumCircular(self, A):
size=len(A)
if size==0:
return 0
else:
cur_minsum,minsum,cur_maxsum,maxsum,total=A[0],A[0],A[0],A[0],A[0]
for i in range(1,size):
cur_minsum=min(cur_minsum,0)+A[i]
minsum=min(minsum,cur_minsum)
cur_maxsum=max(cur_maxsum,0)+A[i]
maxsum=max(maxsum,cur_maxsum)
total+=A[i]
return(max(maxsum,total-minsum) if maxsum>0 else maxsum)
cur_minsum=min(curminsum+A[i],A[i])
minsum=min(cur_minsum,minsum)
cur_maxsum=max(cur_maxsum+A[i],A[i])
maxsum=max(maxsum,cur_maxsum)