53最大连续子序列和
题目描述
最大连续子序列和。(至少包含一个数组)
例子
Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6.
思想 法1 - DP。dp[i]表示以i位置结尾的最大值,dp[i] = max(dp[i-1] + nums[i], nums[i]);
法2 - 贪心。如果之前的和小于0,则从当前数字开始。即如果summ<0,则将summ置0;否则继续summ + num。
法3 - 分治法。 考虑区间[l, r]内的答案如何计算?
令 mid = (l + r) / 2,则该区间的答案是三部分取最大值,分别是:
(a) 区间 [l, mid] 内的答案(递归)。
(b) 区间 [mid + 1, r] 内的答案(递归)。
(c) 跨越 mid和mid+1 的连续子序列。
其中,(c) 部分只需要从 mid 开始向 l 找连续的最大值,以及从 mid+1 开始向 r 找最大值即可,
在线性时间内可以完成。 递归终止条件显然是 l==r ,此时直接返回 nums[l]。
每层时间复杂度是 O(n),总共有 O(logn) 层,故总时间复杂度是 O(nlogn)。
解法1 可以优化空间复杂度,优化后类似法2
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = nums[0]
dp = [0] * len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(dp[i-1] + nums[i], nums[i])
res = max(res, dp[i])
return res
解法2
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = summ = nums[0]
for num in nums[1:]:
if summ < 0:
summ = 0
summ += num
res = max(res, summ)
return res
解法3
class Solution(object):
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return self.helper(0, len(nums)-1, nums)
def helper(self, left, right, nums):
if left == right:
return nums[left]
mid = (left + right) >> 1
lmax = nums[mid]
rmax = nums[mid+1]
lsum = rsum = 0
for i in range(mid, left-1, -1):
lsum += nums[i]**加粗样式**
lmax = max(lsum, lmax)
for i in range(mid+1, right+1):
rsum += nums[i]
rmax = max(rsum, rmax)
return max(max(self.helper(left, mid, nums), self.helper(mid+1, right, nums)), lmax+rmax)