【力扣53-最大子序和】多种解法(2种DP+分治)(python3+go)

题目描述

https://leetcode-cn.com/problems/maximum-subarray/

思路题解

1.动态规划(需额外开辟数组)

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

2.动态规划(不需额外开辟数组)

go代码

func maxSubArray(nums []int) int {
    ans:=nums[0]
    for i:=1;i<len(nums);i++{
        if nums[i]<nums[i]+nums[i-1]{
            nums[i]=nums[i]+nums[i-1]
            ans=max(ans,nums[i])
        }else{
            ans=max(ans,nums[i])
        }

    }
    return ans
}
func max(i,j int)int{
    if i>j{return i}else {return j}
}

在这里插入图片描述

python3代码

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

3.分治法

分治法,最大子序和的分布分三种情况:

  • 在左半部分
  • 在右半部分
  • 横跨两部分(即包括左半部分的最后一个元素,和右半部分的第一个元素
    最后,返回这三种情况的最大值即可,总的时间复杂度O(nlogn)。

注意:第三种情况,以计算右半部分为例,因为必须以右边第一个元素为起点,因此不存在判断加上此节点nums[i]和不加此节点的最大值的情况(即不需要leftBorderSum =max(leftBorderSum+nums[i],nums[i]) ),直接让leftBorderSum =max(leftBorderSum, leftSum)即可。

class Solution(object):
  def maxSubArray(self, nums):
    #左右边界
    left = 0
    right = len(nums)-1
    #求最大和的值
    maxSum = self.divide(nums,left,right)
    return maxSum
    
  def divide(self,nums,left,right):
    #递归出口:如果只有一个元素就返回这个元素
    if left==right:
      return nums[left]
    #求中心点
    center = (left+right)//2
    #1.求子序在中心点左边的和
    leftMaxSum = self.divide(nums,left,center)
    #2.求子序在中心点右边的和
    rightMaxSum = self.divide(nums,center+1,right)
    
    #3.求子序横跨2边的和,分成左边界和和右边界和
    leftBorderSum = nums[center]
    leftSum = nums[center]
    for i in range(center-1,left-1,-1):
      leftSum += nums[i]
      leftBorderSum =max(leftBorderSum, leftSum)
      
    rightBorderSum = nums[center+1]
    rightSum = nums[center+1]
    for i in range(center+2,right+1):
      rightSum += nums[i]
      rightBorderSum =max(rightBorderSum, rightSum)
      
    #左边界的和 + 右边那块的和
    BorderSum = leftBorderSum + rightBorderSum
    return max(leftMaxSum,rightMaxSum,BorderSum)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值