【剑指offer】JZ42 连续子数组的最大和

1 问题

输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
数据范围:
1<=n<=2×10
−100<=a[i]<=100

要求:时间复杂度为 O(n),空间复杂度为
进阶:时间复杂度为 O(n),空间复杂度为

示例1
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18

示例2
输入:[2]
返回值:2

示例3
输入:[-10]
返回值:-10

2 答案

自己写的,逻辑应该没问题,但内存超出限制

class Solution:
    def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
        dp = [[float('-inf')]*len(array) for _ in range(len(array))]
        for i in range(len(array)):
            dp[i][i] = array[i]
        for i in range(len(array)):
            for j in range(i+1, len(array)):
                dp[i][j] = dp[i][j-1] + array[j]
        return max(max(dp[k]) for k in range(len(array)))

官方解

  1. 动态规划

因为数组中有正有负有0,因此每次遇到一个数,要不要将其加入我们所求的连续子数组里面,是个问题,有可能加入了会更大,有可能加入了会更小,而且我们要求连续的最大值,因此这类有状态转移的问题可以考虑动态规划。

  • step 1:可以用dp数组表示以下标i为终点的最大连续子数组和。
  • step 2:遍历数组,每次遇到一个新的数组元素,连续的子数组要么加上变得更大,要么这个元素本身就更大,要么会更小,更小我们就舍弃,因此状态转移为 d p [ i ] = max ⁡ ( d p [ i − 1 ] + array ⁡ [ i ] , array ⁡ [ i ] ) d p[i]=\max (d p[i-1]+\operatorname{array}[i], \operatorname{array}[i]) dp[i]=max(dp[i1]+array[i],array[i])
  • step 3:因为连续数组可能会断掉,每一段只能得到该段最大值,因此我们需要维护一个最大值。
class Solution:
    def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
        dp = [0 for i in range(len(array))] 
        dp[0] = array[0]
        maxsum = dp[0]
        for i in range(1, len(array)):
            dp[i] = max(dp[i-1]+array[i], array[i])
            maxsum = max(maxsum, dp[i])
        return maxsum
  1. 动态规划,空间优化

我们注意到方法一的动态规划在状态转移的时候只用到了i−1的信息,没有使用整个辅助数组的信息,因此可以将数组优化掉。

  • step 1:我们可以使用两个变量迭代来代替数组。
  • step 2:状态转移的时候更新变量y,该轮循环结束的再更新x为y即可做到每次迭代都是上一轮的dp。
  • step 3:遍历数组,每次只要比较取最大值即可。
class Solution:
    def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
        x = array[0]
        y = 0  # 刚开始y(dp[1])还没有值
        maxsum = array[0]
        for i in range(1, len(array)):
            # y, x = max(x+array[i], array[i]), y  # 合起来写不行,不知道为啥
            y = max(x+array[i], array[i])
            x = y
            maxsum = max(maxsum, y)
        return maxsum

https://www.nowcoder.com/share/jump/9318638301699196326030

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouHerGetUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值