题目描述
解题思路
当求某一系列的值和最大最小问题时,很自然的想到了dp求解,dp求解的关键是用一维dp求解还是二维dp。不同维度的dp,dp表示的含义肯定不一样。当然二维dp肯定比一维好想一点,我想到的是二维官方题解给的是一维,那么先讲二维。
二维dp解法
首先从题目条件入手,最长的子序列的长度就等于nums的长度,当知道子序列的长度时你就要找这个长度的哪个子序列的和最大。
我想的是二维dp的行(i)就构建成子序列的长度,列(j)就构建成第j个这个长度子序列的和
举个例子:
dp[1][0]应该就等于-2 和1的求和因为他在第一行(从0开始)说明这一行代表长度为2的子序列,然后第0列就表示第一个长度为2的子序列
同理:dp[2][1]就应该是1,-3,4的和。dp[0]就和nums相等,既为子序列长度为1的子序列
直接看代码
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n=len(nums)
if n==1:
return nums[0]
dp=[[float('-inf')]*n for _ in range(n)]
dp[0]=nums
result=max(nums)
for i in range(1,n):
for j in range(n-i):
dp[i][j]=dp[i-1][j]+nums[j+i]
if dp[i][j]>result:
result=dp[i][j]
return result
这个代码在210个样例中能通过200个样例,其余的超时,但是比较好想到。这里要注意的是dp的初值不能赋0要赋负无穷,因为有可能nums为全负数。
一维dp解法
一维dp的简要意思就是在这道题,你要把题目要求的东西和你所想要表达的东西压缩到一维来表示。
这样我们就把子序列压缩到了以某个数字结尾的序列,dp[i]就表示以数字i结尾的子序列的最大值是多少
当dp[i-1]<0时,dp[i]=nums[i]如果前一步小于0加了的话只会越来越小
当dp[i-1]>0时,dp[i]=dp[i-1]+nums[i]如果前一步大于0那么我加上他的子序列肯定很增大我的值
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
size = len(nums)
if size == 0:
return 0
dp = [0 for _ in range(size)]
dp[0] = nums[0]
for i in range(1, size):
if dp[i - 1] >= 0:
dp[i] = dp[i - 1] + nums[i]
else:
dp[i] = nums[i]
return max(dp)