剑指 Offer 42. 连续子数组的最大和
Posted 炫云云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 42. 连续子数组的最大和相关的知识,希望对你有一定的参考价值。
剑指 Offer 42. 连续子数组的最大和
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
动态规划
动态规划解析:
- 状态定义: 设动态规划列表 d p , d p [ i ] d p, d p[i] dp,dp[i] 代表以元素 n u m s [ i ] n u m s[i] nums[i] 为结尾的连续子数组最大和。
- 为何定义最大和 d p [ i ] d p[i] dp[i] 中必须包含元素 nums [ i ] : [i]: [i]: 保证 d p [ i ] d p[i] dp[i] 递推到 d p [ i + 1 ] d p[i+1] dp[i+1] 的正确性; 如果不包含 n u m s [ i ] n u m s[i] nums[i], 递推时则不满足题目的 连续子数组 要求。
转移方程: 若 d p [ i − 1 ] ≤ 0 d p[i-1] \\leq 0 dp[i−1]≤0 , 说明 d p [ i − 1 ] d p[i-1] dp[i−1] 对 d p [ i ] d p[i] dp[i] 产生负贡献, 即 d p [ i − 1 ] + d p[i-1]+ dp[i−1]+ nums [ i ] [i] [i] 还不 如 nums [ i ] [i] [i] 本身大。
- 当 d p [ i − 1 ] > 0 d p[i-1]>0 dp[i−1]>0 时:执行 d p [ i ] = d p [ i − 1 ] + d p[i]=d p[i-1]+ dp[i]=dp[i−1]+ nums [ i ] ; [i] ; [i];
- 当 d p [ i − 1 ] ≤ 0 d p[i-1] \\leq 0 dp[i−1]≤0 时:执行 d p [ i ] = d p[i]= dp[i]= nums [ i ] ; [i] ; [i];
初始状态: d p [ 0 ] = n u m s [ 0 ] d p[0]=n u m s[0] dp[0]=nums[0], 即以 n u m s [ 0 ] n u m s[0] nums[0] 结尾的连续子数组最大和为 nums [ 0 ] [0] [0] 。
返回值:返回 d p d p dp 列表中的最大值,代表全局最大值。
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in range(1,len(nums)):
nums[i] += max(nums[i-1],0)
return max(nums)
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# dp[i] 代表 i 之前的所有元素的连续子数组最大和
n = len(nums)
dp = [0] * (n + 1)
ans = nums[0]
for i in range(1, n+1):
dp[i] = max(nums[i-1], dp[i-1] + nums[i-1])
ans = max(ans, dp[i])
return ans
前缀和的思路
由于 连续子数组最大和 = 某个位置的前缀和 - 之前遇到的最小的前缀和
因此在计算前缀和的时候同时记录一下最小值,计算一下结果
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
min_val = 0
pre = 0
res = nums[0]
for key in nums:
pre += key
res = max(pre-min_val,res)
min_val = min(pre , min_val)
return res
参考
以上是关于剑指 Offer 42. 连续子数组的最大和的主要内容,如果未能解决你的问题,请参考以下文章