53. 最大子序和(python3)

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

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

 

解题思路:

动态规划普通解法见代码1,转移方程为dp[i]=max{dp[i-1]+nums[i], nums[i]} ,其中dp[i]为以nums[i]结尾的连续子数组的和。由于dp[i]的值只与dp[i-1]有关,所以还可以进一步优化,使用滚动数组思想。

 

滚动数组”就是把数据暂存起来然后再利用,比如这道题dp[i]只与dp[i-1]有关,则可以用p记录dp[i-1],用q记录dp[i],此时for循环里的语句变为:

q = max{p+nums[i], nums[i]}

p = q

即每次更新p用于下次循环

简写可写做:

q = max{q+nums[i], nums[i]}   (等号左边的是新q,等号右边的是上一循环的q)

 

若dp[i]的值只与dp[i-1]、dp[i-2]有关,举个例子:dp[i]=dp[i-1]+dp[i-2],用p记录dp[i-1], q记录dp[i-2],r记录dp[i],则for循环改为:

r = p + q

q = p

p = r

即用p去更新q、r去更新p用于下次循环(下一次循环中i+1,原i-1变为i,i-2变为i-1,所以用q=p,p=r,注意q=p在前,若p=r写在前面,q=p则更新成了r的值)

 

了解了滚动数组后再看这道题,需要对滚动数组进行改造,因为此题不是为了求dp[i],从代码1可以看出dp[i]求完后还需要遍历一遍dp数组求出最大数,所以需要在滚动时进行最大值的记录。

即for循环中可写做:

q = max{q+nums[i], nums[i]} 

res = max(q, res)

即代码2所示

这时空间复杂度就降到了O(1)

 

代码1:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        m = len(nums)
        dp = [0]*m

        dp[0] = nums[0]
        if(m == 1):
            return dp[0]
        
        for i in range(1, m):
            dp[i] = max(dp[i - 1]+nums[i], nums[i])

        maxvalue = dp[0]
        for i in range(1, m):
            if(dp[i] > maxvalue):
                maxvalue = dp[i]
        
        return maxvalue

代码2:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = nums[0]
        cur = 0

        for i in nums:
            cur = max(cur + i, i)
            res = max(cur, res)

        return res

 

测试:

if __name__ == "__main__":
    nums = [-2,1,-3,4,-1,2,1,-5,4]
    res = Solution().maxSubArray(nums)
    print(res)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值