leetcode 每日一题 53. 最大子序和

Posted nil_f

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 每日一题 53. 最大子序和相关的知识,希望对你有一定的参考价值。

动态规划

思路:

由于题目只要求得到最大和,故可以遍历数组nums,遍历的同时把每个元素的值更新为当前位置到之前所能得到的最大和,遍历完成后返回数组中最大值即可。更新的动态规划转移方程为:nums[i] = nums[i] + max(nums[i-1],0)

代码:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1, len(nums)):
            nums[i]= nums[i] + max(nums[i-1], 0)
        return max(nums)

分治法

思路:

对于区间 [ l , r ] ,要获得区间内最大子段和,令m = (l+r)/2,我们可以把区间分为 [ l , m ] 和 [ m+1 , r ] 进行分治求解。

对于一个区间 [ l , r ] :

 

  • lSum表示 [ l , r ] 以 l 为左端点的最大字段和
  • rSum表示 [ l , r ] 以 r 为右端点的最大字段和
  • mSum表示 [ l , r ] 最大字段和
  • iSum表示 [ l , r ] 区间和

这里我们要找到区间Q [ l , r ] 这四个字段和两个子数组q1 [ l , m ] ,q2 [ m+1 ,r] 之间的关系。

Q.ISum = max(q1.lSum,q1.iSum+q2.lSum)

Q.rSum = max(q2.rSum,q2.iSum+q1.rSum)

Q.mSum = max(max(q1.mSum,q2.mSum),q1.rSum+q2.lSum)

Q.iSum = q1.iSum+q2.iSum

对2个子区间继续进行拆分,直到区间只剩下一个元素,这个时候区间四个值均等于这个元素,接着按照上面关系,两两回升合并,得到最后答案。

代码:

class Section:
    def __init__(self,lSum,rSum,iSum,mSum):
        self.lSum = lSum
        self.rSum = rSum
        self.iSum = iSum
        self.mSum = mSum
class Solution:
    def pushUp(self,lSub,rSub):
        iSum = lSub.iSum + rSub.iSum
        lSum = max(lSub.lSum,lSub.iSum+rSub.lSum)
        rSum = max(rSub.rSum,rSub.iSum+lSub.rSum)
        mSum = max(max(lSub.mSum,rSub.mSum),lSub.rSum+rSub.lSum)
        return Section(lSum,rSum,iSum,mSum)
    def getSection(self,nums,l,r):
        if l == r:
            return Section(nums[l],nums[l],nums[l],nums[l])
        m = (l+r)//2
        lSub = self.getSection(nums,l,m)
        rSub = self.getSection(nums,m+1,r)
        return self.pushUp(lSub,rSub) 
    def maxSubArray(self, nums: List[int]) -> int:
        return self.getSection(nums,0,len(nums)-1).mSum

 

以上是关于leetcode 每日一题 53. 最大子序和的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:81.最大子序和

LeetCode 解题大纲(每日一题C++自用)

Leetcode 53. 最大子序和

LeetCode 53. 最大子序和

LeetCode-53-最大子序和

LeetCode-53-最大子序和