1 问题
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
数据范围:
1<=n<=2×10
−100<=a[i]<=100
要求:时间复杂度为 O(n),空间复杂度为
进阶:时间复杂度为 O(n),空间复杂度为
示例1
输入:[1,-2,3,10,-4,7,2,-5]
返回值:18
说明:经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18
示例2
输入:[2]
返回值:2
示例3
输入:[-10]
返回值:-10
2 答案
自己写的,逻辑应该没问题,但内存超出限制
class Solution:
def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
dp = [[float('-inf')]*len(array) for _ in range(len(array))]
for i in range(len(array)):
dp[i][i] = array[i]
for i in range(len(array)):
for j in range(i+1, len(array)):
dp[i][j] = dp[i][j-1] + array[j]
return max(max(dp[k]) for k in range(len(array)))
官方解
- 动态规划
因为数组中有正有负有0,因此每次遇到一个数,要不要将其加入我们所求的连续子数组里面,是个问题,有可能加入了会更大,有可能加入了会更小,而且我们要求连续的最大值,因此这类有状态转移的问题可以考虑动态规划。
- step 1:可以用dp数组表示以下标i为终点的最大连续子数组和。
- step 2:遍历数组,每次遇到一个新的数组元素,连续的子数组要么加上变得更大,要么这个元素本身就更大,要么会更小,更小我们就舍弃,因此状态转移为 d p [ i ] = max ( d p [ i − 1 ] + array [ i ] , array [ i ] ) d p[i]=\max (d p[i-1]+\operatorname{array}[i], \operatorname{array}[i]) dp[i]=max(dp[i−1]+array[i],array[i])
- step 3:因为连续数组可能会断掉,每一段只能得到该段最大值,因此我们需要维护一个最大值。
class Solution:
def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
dp = [0 for i in range(len(array))]
dp[0] = array[0]
maxsum = dp[0]
for i in range(1, len(array)):
dp[i] = max(dp[i-1]+array[i], array[i])
maxsum = max(maxsum, dp[i])
return maxsum
- 动态规划,空间优化
我们注意到方法一的动态规划在状态转移的时候只用到了i−1的信息,没有使用整个辅助数组的信息,因此可以将数组优化掉。
- step 1:我们可以使用两个变量迭代来代替数组。
- step 2:状态转移的时候更新变量y,该轮循环结束的再更新x为y即可做到每次迭代都是上一轮的dp。
- step 3:遍历数组,每次只要比较取最大值即可。
class Solution:
def FindGreatestSumOfSubArray(self , array: List[int]) -> int:
x = array[0]
y = 0 # 刚开始y(dp[1])还没有值
maxsum = array[0]
for i in range(1, len(array)):
# y, x = max(x+array[i], array[i]), y # 合起来写不行,不知道为啥
y = max(x+array[i], array[i])
x = y
maxsum = max(maxsum, y)
return maxsum
https://www.nowcoder.com/share/jump/9318638301699196326030