53. 最大子序和

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

解法一:暴力

遍历所有长度的连续子段,but超时

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = -sys.maxsize
        for i in range(len(nums)):
            for j in range(i, -1, -1):
                res = max(res, sum(nums[j:i+1]))
        return res

解法二:dp

摘自《计算机算法设计与分析》王晓东 第3版

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        sum = nums[0]  #初始累加和
        b = nums[0]  #dp初始状态,0号
        for i in range(1, len(nums)):  #从1号开始
            if b > 0:
                b += nums[i]
            else:
                b = nums[i]
            sum = max(b, sum)
        return sum

2020.3.29

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [0] * n
        res = nums[0]
        if n == 1:
            return res
        dp[0] = nums[0]    #初始
        #用dp[i]记录0~i处最大子序和(包括i)
        for i in range(1, n):
            if dp[i-1] < 0:    #若前面的和小于0,则舍弃
                dp[i] = nums[i]
            else:
                dp[i] = dp[i-1] + nums[i]
            res = max(res, dp[i])     #更新最大和
        return res

2021.10.13 nums[0..i] 中的「最大的子数组和」为 dp[i]。

问题:能用 dp[i] 推出 dp[i+1] 吗?(与300. 最长上升子序列的问题类似)

实际上是不行的,因为子数组一定是连续的,按照我们当前 dp 数组定义,并不能保证 nums[0..i] 中的最大子数组与 nums[i+1] 是相邻的,也就没办法从 dp[i] 推导出 dp[i+1]。

改进:以 nums[i] 为结尾的「最大子数组和」为 dp[i]。

class Solution:
    def maxSubArray(self, nums) -> int:
        n = len(nums)
        if n == 0: return 0
        if n == 1: return nums[0]
        dp = [0] * n
        dp[0] = nums[0]  # 初始
        res = dp[0]

        for i in range(1, n):
            dp[i] = max(nums[i], dp[i - 1] + nums[i])
            res = max(res, dp[i])
        return res

改进:状态压缩 由于迭代过程中只用到dp[i-1]和dp[i],用dp_0和dp_1代替节省空间

class Solution:
    def maxSubArray(self, nums) -> int:
        n = len(nums)
        if n == 0: return 0
        if n == 1: return nums[0]
        dp = [0] * n
        dp_0 = nums[0]  # 初始
        res = dp_0

        for i in range(1, n):
            dp_1 = max(nums[i], dp_0 + nums[i])
            dp_0 = dp_1
            res = max(res, dp_0)
        return res

最后更新于