美文网首页
【简单】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 最大子序和

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

  • LeetCode-53 最大子序和

    动态规划 分治 题目 https://leetcode-cn.com/problems/maximum-subar...

  • Leetcode-53 最大子序和

    53. 最大子序和[https://leetcode-cn.com/problems/maximum-subarr...

  • 最长连续子序和问题

    0X00 算法总结 最大子序和 53. 最大子序和 这是一道非常经典的 dp 问题, 以最大子序和的最后一个数字来...

  • leetcode-53 最大子序和 python3 贪心解法

    解题思路:记录当前元素nums[i],当前序列的最大值result_temp,总的最大值result1.如果元素全...

  • 【5月】LeetCode:我怎么还是这么菜

    5.3 题目链接 53. 最大子序和 很喜欢的解法(DP) 官方解(分治) 参考题解:最大子序和 但是仔细观察「方...

  • 动态规划1

    53. 最大子序和 70, 爬楼梯

  • ARTS 打卡 3

    Algorithm 53. 最大子序和简单的解题思路是O(nlogn),使用一维数组记录index前面所有数的和,...

  • [Leetcode] 53. 最大子序和

    53. 最大子序和 来源: 53. 最大子序和 1. 题目描述 给定一个整数数组 nums ,找到一个具有最大和...

  • 最大子序和

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

网友评论

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

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