动态规划--最大连续子序列和

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[i]表示以i位置结尾的最大值
        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
        # The maxSum including mid and mid+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)

猜你喜欢

转载自blog.csdn.net/lgy54321/article/details/90704414