53. 最大子序和

  • 难度简单
  • 本题涉及算法贪心 动态规划
  • 思路贪心 动态规划
  • 类似题型:

题目 53. 最大子序和

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

示例:

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

进阶:

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

方法一 贪心

  • 这道题用动态规划的思路并不难解决,比较难的是后文提出的用分治法求解,但由于其不是最优解法,所以先不列出来
  • 动态规划的是首先对数组进行遍历,当前最大连续子序列和为 sum,结果为 ans
  • 如果 sum > 0,则说明 sum 对结果有增益效果,则 sum 保留并加上当前遍历数字
  • 如果 sum <= 0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字
  • 每次比较 sumans 的大小,将最大值置为 ans ,遍历结束返回结果
  • 时间复杂度:$O(n)$
class Solution(object):
    def maxSubArray(self, nums):
        ans = nums[0]
        numsSum = 0
        for num in nums:
            if numsSum >0:
                numsSum += num
            else:
                numsSum = num
            ans = max(numsSum,ans)
        return ans

动态规划

  • 最重要的是搞清楚 dp 数组所存储元素的意义,这里要明确 dp[i] 存储的不是从 0 到 i 这个范围内所得到的最大的连续子数组的和,而是 以 nums[i] 为结尾的子数组所能达到的最大的和
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        if len(nums) == 1:
            return nums[0]
        # 下面为nums长度至少为2的情况
        res = nums[0]  # 先设定一个初始值(假设第一个数是可获得的最小值)
        for i in range(1, len(nums)):
            nums[i] = max(nums[i], nums[i] + nums[i - 1])  # 更新后的nums[i]存储 以原始num[i]为结尾的子数组和的最大值
            res = max(res, nums[i])  # 更新最大值
        return res