动态规划,将dp定义为以num[i]结尾的最大子数组和,这是子序列或者子数组的常见做法
这样转移方程显而易见了
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: 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)
滑窗,正确性在于最大子数组一定是以正数开头的或者是全负的最小负数
所以只有当窗口小于0时缩小窗口,这样遍历到所有以正数为开头的子数组了
且一直记录答案
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
win = 0
res = -0x3f3f3f3f
right = 0
left = 0
while right < len(nums):
win += nums[right]
right += 1
res = max(res,win)
while win < 0:
win -= nums[left]
left += 1
return res
前缀和,注意前缀和有一位的偏移
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
presum = [0]
for i in nums:
presum.append(presum[-1] + i)
res = nums[0]
minval = 0x3f3f3f3f
for i in range(len(nums)):
minval = min(minval,presum[i]) #记录[0:i-1]里最小的前缀和
res = max(res,presum[i+1]-minval) #presum[i+1]这才是以num[i]结尾的前缀和
return res