【LeetCode】53. 最大子序列

问题描述

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

给定一个整数数组编号,找到具有最大和的连续子数组(至少包含一个数字)并返回其和。
如果您已经找到了O(n)的解决方案,那么尝试使用分治方法编写另一个解决方案,这种方法更加微妙。

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
期待结果: [4,-1,2,1] 存在最大和为 6.

Python 实现

实现一:依次记录遍历到数组当前位置时得到的相对最大和。

这里的相对是指,当前值与加上当前值后的结果两者之间的较大值。该算法不考虑数值的具体特征,只记录遍历过程中子序列的和的结果。每当出现一个值,比上一个子序列所有值的总和还要大,那么从该值重新开始一个子序列。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        
        maxSum = [nums[0]]
        for i in range(1, len(nums)):
            maxSum.append(max(nums[i], nums[i] + maxSum[i-1]))
        return max(maxSum)

 

实现二:分而治之

基本思路就是从中间将数组分开,从中间开始分别往两个方向去计算最大和,取两者较大值或者两者之和。

这里需要注意的是,求和的时候不再像上面那样找间断的子序列,而是从起点开始,依次加上新的值得到新的结果。这样子才能保证当我们取两者之和时,得到的结果依然是一个连续子序列求和的结果。

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        # Basis condition.
        if len(nums) < 2:
            return nums[0]
        
        maxSum = leftSum = rightSum = float('-inf')
        l = r = 0
        
        # Start from the middle to right.
        for i in range(len(nums)//2, len(nums)):
            r += nums[i]
            rightSum = r if r > rightSum else rightSum
            
        # Start from the middle to left.
        for i in range(len(nums)//2-1, -1, -1):
            l += nums[i]
            leftSum = l if l > leftSum else leftSum
            
        # Connect the result between two parts.
        total = leftSum + rightSum
        
        return max(total, self.maxSubArray(nums[ : len(nums)//2]), self.maxSubArray(nums[len(nums)//2 : ]))

链接:https://leetcode.com/problems/maximum-subarray/

发布了46 篇原创文章 · 获赞 29 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章