最大子序和问题leetcode53leetcode918
Posted miliang NLP
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子序和问题leetcode53leetcode918相关的知识,希望对你有一定的参考价值。
leetcode53:
题目:
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
题解:本题的解决思路采用动态规划的思想,从第0个元素开始,每次保存到当前位置的最大子序和,存储到数据DP中,DP中最大的数即为数组nums的最大子序和。
代码:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if not nums: return 0
dp = [0] * len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(nums[i], nums[i] + dp[i - 1])
return max(dp)
leetcode 918(与53相比就是有环和无环的区别):
题目:
给定一个由整数数组 A 表示的环形数组 C,求 C 的非空子数组的最大可能和。
在此处,环形数组意味着数组的末端将会与开头相连呈环状。(形式上,当0 <= i< A.length 时 C[i] = A[i],且当 i >= 0 时 C[i+A.length] =C[i])
此外,子数组最多只能包含固定缓冲区 A 中的每个元素一次。(形式上,对于子数组 C[i], C[i+1], ..., C[j],不存在 i<= k1, k2 <= j 其中 k1 % A.length =k2 % A.length)
示例:
输入:[5,-3,5]
输出:10解释:从子数组 [5,5] 得到最大和 5 + 5 = 10
题解:
分为以下两种情况
(1)最大值在中间部分,如图1所示,则和上题(leetcode 53)一样求解
图1
(2)最大在两端的情况,如图2所示,则中间部分则为最小子序和问题(为题leetcode 53的对偶问题),利用数组的总和减去最小子序和就可以得到最大子序和,但是当数组中的数全为负数是,数组总和和最小子序和相等,相减则为0,此时,应该取情况1的结果。
图2
代码:
class Solution:
def maxSubarraySumCircular(self, nums: List[int]) -> int:
length = len(nums)
nums_sum, DP_max, DP_min = sum(nums), [0]*length, [0]*length
DP_max[0], DP_min[0] = nums[0], nums[0]
for i in range(1, length):
DP_max[i] = max(nums[i], DP_max[i-1]+nums[i])
DP_min[i] = min(nums[i], DP_min[i-1]+nums[i])
if nums_sum == min(DP_min): #所有的数都是负数的情况
return max(DP_max)
else:
return max(max(DP_max), nums_sum-min(DP_min))
以上是关于最大子序和问题leetcode53leetcode918的主要内容,如果未能解决你的问题,请参考以下文章