——目标:求和最大的连续子序列
暴力做法是分两层遍历数组,求以i为开头的子序列和最大。复杂度为n2.
——思路1 :动态规划
将大问题分解为:求从头开始到第i个元素间构成的数组的子序列数组和最大。其实这个说法不太准确,或者说跟我之前想的dp并不一样。实际思路实际可以简化为两个缓存curSum和maxSum,curSum保存暂时子列和,maxSum保存已知最大子列和。遍历到i时,判断curSum[i-1]是否小于0,如果小于0则curSum[i]=n[i](子序列和重新开始统计),否则curSum[i]=n[i]+curSum[i](子序列和加上本次i项),同时判断maxSum和curSum[i]的关系以决定是否更新maxSum。
之所以说跟我之前想的不一样,是因为我之前一直以为dp一般都需要空间换时间的一个同规模空间。但是实际并没有,大概是我陷入思维定式了。
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
thissum = {}
maxs = -100000000000
for k,v in enumerate(nums):
if k==0:
thissum[k]=v
else:
thissum[k] = max(thissum[k-1]+v,v)
for _,v in thissum.items():
maxs = max(maxs,v)
return maxs
ps:边际testcase我想到的有全是0,全是负数,加和超过max_int(如果类型有限制的话)。具体如何处理要看要求。
——思路2:分治法
具体是,将大数组中找最大分为三种情况,取中间点:1 最大在中间左边 ;2 最大在中间右边 ;3 最大包括中间。那么递归前两种情况,然后单独计算第三种情况,再返回三者中最大的那个就可以。我其实不太喜欢这个方法,因为需要递归。
——总结
计划是0.5小时,总用时40min,还是看的别人的思路才做完。
反思了下自己之前的思路,是自己想的太复杂,或者像之前说的陷入思维定式了,以为一定要有个缓存数组,而且这个数组一定要保存到这个点为止的最大子列和,实际完全没有必要。
好吧,我还是想说,这种方法不是dp。