【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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章