【leetcode】53. 最大子序和

53. 最大子序和(題目源地址

給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。

示例:

輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。

方法一:

貪心法
從左往右掃描,計算從下標爲0到當前位置子序列最大和與當前子序列的較大值, 然後再與全局最大值相比較,得到新的全局最大值

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        curr_sum = max_sum = nums[0]

        for i in range(1, n):
            curr_sum = max(nums[i], curr_sum + nums[i])
            max_sum = max(max_sum, curr_sum)

        return max_sum

方法二:

動態規劃法
從左往右掃描,用一個數組記錄當前位置下(從左往右子序列和的最大值), 然後取所有位置下記錄值的最大值,如下:
輸入: [-2,1,-3,4,-1,2,1,-5,4]
記錄: [-2,1,-2,4,3,5,6,1,5]
最大值爲6,則結果爲6
備註:當前值加上左邊的子序列的最大值若大於當前值,則說明左邊存在一個子序列加上當前值爲最大序列和。

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

        return max(sums)

思考了一下覺得可以直接在nums上更新,當前位置的最大子序列和,可以省去外部的內存開銷。

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

        return max(nums)

方法三:

分治法
參考了官方的解題思路,這裏就不詳細介紹了,感興趣的可以直接點進去看,設計的還是非常巧妙的

class Solution:
    def cross_sum(self, nums, left, right, p): 
            if left == right:
                return nums[left]

            left_subsum = float('-inf')
            curr_sum = 0
            for i in range(p, left - 1, -1):
                curr_sum += nums[i]
                left_subsum = max(left_subsum, curr_sum)

            right_subsum = float('-inf')
            curr_sum = 0
            for i in range(p + 1, right + 1):
                curr_sum += nums[i]
                right_subsum = max(right_subsum, curr_sum)

            return left_subsum + right_subsum   
    
    def helper(self, nums, left, right): 
        if left == right:
            return nums[left]
        
        p = (left + right) // 2
            
        left_sum = self.helper(nums, left, p)
        right_sum = self.helper(nums, p + 1, right)
        cross_sum = self.cross_sum(nums, left, right, p)
        
        return max(left_sum, right_sum, cross_sum)
        
    def maxSubArray(self, nums):
        return self.helper(nums, 0, len(nums) - 1)

今天打卡完成!明天再接再厲!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章