美文网首页
【简单】Leetcode-53 最大子序和

【简单】Leetcode-53 最大子序和

作者: 砥砺前行的人 | 来源:发表于2021-05-10 09:24 被阅读0次

    题目描述

    给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
    输出:6
    解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
    

    解法一

    暴力求解。思路简单,时间复杂度为 O(n*n),会超时

    class Solution:
        def maxSubArray(self, nums: List[int]) -> int:
            # 暴力
            if not nums: return 0
            res = nums[0]
            for l in range(len(nums)):
                for j in range(l, len(nums)):
                    res = max(res, sum(nums[l:j+1]))
            return res
    

    解法二

    动态规划。比较迭代过程中比较当前值与 上一次的dp值的和是否有超过当前值,否则只保留当前值填入当前dp即可。时间复杂度O(n), 空间复杂度 O(n)

    class Solution:
        def maxSubArray(self, nums: List[int]) -> int:
            # 动态规划
            dp = [nums[0]] * len(nums)
            dp[0] = nums[0]
            for i in range(1, len(nums)):
                # 如果当 num[i] > dp[i-1] + nums[i],那么可以表示之前的可以舍弃重新开始
                dp[i] = max(nums[i], dp[i-1] + nums[i])
            return max(dp)
    

    解法三

    动态规划。时间复杂度O(n), 空间复杂度 O(1)。

    class Solution:
        def maxSubArray(self, nums: List[int]) -> int:
            # 动态规划
            res = cur = nums[0]
            for i in range(1, len(nums)):
                cur = max(nums[i], cur + nums[i])
                res = max(res, cur)
            return res
    

    解法四

    回溯 + 分治。分为左中右。看注释理解中间区域

    class Solution:
        def maxSubArray(self, nums: List[int]) -> int:
            if not nums: return 0
            return self.__max_sub_array(nums, 0, len(nums) - 1)
    
        def __max_sub_array(self, nums, left, right):
            if left == right:
                return nums[left]
            mid = left + ((right - left) >> 1)
            # 回溯 + 分治
            return max(self.__max_sub_array(nums, left, mid),
                       self.__max_sub_array(nums, mid + 1, right),
                       self.__max_cross_array(nums, left, mid, right))
    
        def __max_cross_array(self, nums, left, mid, right):
            # 一定包含 nums[mid] 元素的最大连续子数组的和,
            # 思路是看看左边"扩散到底",得到一个最大数,右边"扩散到底"得到一个最大数
            # 然后再加上中间数
            left_sum_max, start_left, s1 = 0, mid - 1, 0
            while start_left >= left:
                s1 += nums[start_left]
                left_sum_max = max(left_sum_max, s1)
                start_left -= 1
    
            right_sum_max, start_right, s2 = 0, mid + 1, 0
            while start_right <= right:
                s2 += nums[start_right]
                right_sum_max = max(right_sum_max, s2)
                start_right += 1
            return left_sum_max + nums[mid] + right_sum_max
    

    相关文章

      网友评论

          本文标题:【简单】Leetcode-53 最大子序和

          本文链接:https://www.haomeiwen.com/subject/esgudltx.html