这道题是Leetcode#53。个人觉得它很烦人。首先,看题不清楚的话,就变成找max和second max相加了。
那在找dynamic programming的公式的时候,也不好找。
总而言之,对我来说,我觉得很烦恼,觉得它不属于easy的那种。easy的那种应该是比较直接的。当然也许medium和hard更难就对了。
我是先在DP方面想,然后觉得nums[i:j]应该是可以从nums[i:j-1]和nums[i+1,j]之间推倒出来。结果搞错了,虽然搞了个蛋疼的2维数组,除了学习和练习Python的二维数组之外没什么用。浪费时间和空间。在超长的输入面前就超时了。
# 费时费力的代码如下,千万不要模仿!!
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
results = [[0 for j in range(len(nums))] for i in range(len(nums))] # 这个还是不错的,虽然没有什么用
max = nums[0] # trick: let max be the first element
results[0][0] = nums[0]
for j in range(1, len(nums)):
for i in range(j, -1, -1):
if i == j:
results[i][j] = nums[i]
else:
results[i][j] = nums[j] + results[i][j - 1] #这里我把DP的公式搞错特了。
if results[i][j] > max: #这里我也想就着loop,一次把max找出来,不再单独循环了。
max = results[i][j]
return max
结果发现一维的DP可以解决这个问题。我完全没有get it。故事的精髓是到第ith元素,如果前面的一串到i-1的数字之和是正数,那么对我是有用处的,我把它加上ith元素,就是我能组成的包括ith元素的maximum subarray。如果是负数或0,那么就没有什么用了,最大就是ith元素了。这个帖子讲的好清楚。https://leetcode.com/problems/maximum-subarray/discuss/20193/DP-solution-and-some-thoughts
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
results = [0 for j in range(len(nums))]
# trick: let max be the first element
results[0] = nums[0]
for i in range(1, len(nums)):
if results[i-1] > 0: # 这次就比较清楚了
results[i] = nums[i] + results[i-1]
else:
results[i] = nums[i] # forget about the useless i-1 elements before me
maxV = max(results)
return maxV
那好,下面就是去掉DP的数组,因为我们只用到前面的一个,第i-1th。实际上这个值不需要用数组来特别保存的,只需要一个数。只有当DP用到前面的很多数的时候,才值得用数组把它们都存下来。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# trick: let max be the first element
results = nums[0]
maxV = results
for i in range(1, len(nums)):
if results > 0:
results = nums[i] + results
else:
results = nums[i] # forget about the useless i-1 elements before me
# or in Python, one can write
# results = max(nums[i], nums[i]+results)
if results > maxV:
maxV = results
# or in Python
# maxV = max(results, maxV)
return maxV
这样一写,还是比较清楚哈。也许就是个EASY难度。思路不清醒还是不行。
题目作者还challenge大家用divide and conquer来解这道题,其实现在也是比较清楚了。
到ith元素(包含ith元素)的最优解是二选一:使用前i-1元素,不使用前i-1元素。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
def maxSubArrayHelper(nums: List[int]):
if (len(nums) == 0):
return (0,0)
if (len(nums) == 1):
return (nums[0],nums[0])
maxV, result = maxSubArrayHelper(nums[:len(nums)-1])
result = max(nums[len(nums)-1]+result, nums[len(nums)-1])
maxV = max(maxV, result)
return (maxV, result)
maxV, result = maxSubArrayHelper(nums)
return maxV