Leetcode-最大子数组和(前缀和加贪心算法/动态规划)

99 阅读1分钟

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

前缀和加贪心算法,时间复杂度为O(n)

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)

        # Step 1: 计算前缀和数组 preSum
        preSum = []
        tmp = 0
        for i in range(n):
            tmp += nums[i]
            preSum.append(tmp)

        # Step 2: 找到最大子数组和
        maxSum = preSum[0]
        minPreSum = 0

        for i in range(n):
            maxSum = max(maxSum, preSum[i] - minPreSum)
            minPreSum = min(minPreSum, preSum[i])

        return maxSum

动态规划: 动态规划的核心思想是利用子问题的最优解来构建原问题的最优解。对于这个问题,可以定义一个状态数组 dp,其中 dp[i] 表示以 nums[i] 结尾的最大子数组和。

具体的动态规划转移方程可以如下定义:

dp[i] = max(nums[i], dp[i-1] + nums[i])

意思是,以第 i 个元素结尾的最大子数组和,要么是只包含第 i 个元素本身,要么是包含了前面的最大子数组和,并且加上第 i 个元素。然后,我们在整个数组中找到所有以每个元素结尾的子数组的最大和,最终的答案即为所有 dp 数组中的最大值。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)

        # 初始化动态规划数组
        dp = [0] * n
        dp[0] = nums[0]

        # 递推计算 dp 数组
        for i in range(1, n):
            dp[i] = max(nums[i], dp[i-1] + nums[i])

        # 返回 dp 数组中的最大值
        return max(dp)