最大子序和--动态规划

问题来源最大子序和

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

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

1. O ( n 2 ) O(n^2) O(n2)算法

这是一种暴力算法。两层遍历将所有的可能子列表取得,并计算该子列表和。第一遍遍历,遍历以nums[i]开端的子列表;第二遍遍历,给定开端nums[i],遍历以nums[j]结束的子列表。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = []
        # 以nums[i]为开端的子列表
        for i in range(len(nums)):
            # 以nums[j]为结束的子列表
            # 即子列表nums[i: j]
            for j in range(i+1, len(nums)+1):
                temp = sum(nums[i: j])
                res.append(temp)
        # 返回res中的最大值
        return max(res)

这种算法超时。

2. O ( n ) O(n) O(n)算法

实际上,暴力算法里有很多重复计算,比如,以nums[0]为开端的子列表,实际上包含了以nums[1]为开端的子列表计算,也就是说,计算以nums[0]为开端的子列表,可以通过计算以nums[1]为开端的子列表得到。

动态规划:状态定义状态转移方程边界值

  • 状态定义: d ( i ) d(i) d(i),以nums[i]为开端的最大子序和
  • 状态转移方程:
    d ( i ) = { n u m s [ i ] if d ( i + 1 ) < 0 n u m s [ i ] + d ( i + 1 ) if d ( i + 1 ) ≥ 0 d(i)=\left\{ \begin{array}{lll} nums[i] &\text{if}& d(i+1)<0\\ nums[i]+d(i+1) &\text{if}& d(i+1)\ge0\\ \end{array}\right. d(i)={nums[i]nums[i]+d(i+1)ififd(i+1)<0d(i+1)0
  • 边界值:
    d ( i ) = { n u m s [ − 1 ] if i = l e n ( n u m s ) − 1 0 if i ≥ l e n ( n u m s ) d(i)=\left\{ \begin{array}{lll} nums[-1] &\text{if}& i=len(nums)-1\\ 0 &\text{if}& i\ge len(nums)\\ \end{array}\right. d(i)={nums[1]0ififi=len(nums)1ilen(nums)

代码如下。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        d = [False for i in range(len(nums))]
        # 遍历每一个以nums[i]为开端的最大子序和
        for i in range(len(nums)-1, -1, -1):
            if i == len(nums) - 1:
                d[-1] = nums[-1]
            else:
                d[i] = nums[i] if d[i+1] < 0 else nums[i] + d[i+1]
        # 选出其中最大值
        return max(d)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值