918. 环形子数组的最大和

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
【方法一】
这道题的简单版本是最大子序和问题,所以本题可以拆分为两个部分来解。
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)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值