LeetCode题目(Python实现):最大子序和

题目

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

示例 :

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

进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

自己的想法

算法实现

class Solution:
    def maxSubArray(nums: List[int]) -> int:
        lenth = len(nums)
        max = float("-inf")
        sum = 0
        i = 0
        while i != lenth:
            if sum == 0 and nums[i] <= 0:
                sum = nums[i]
            else:
                sum += nums[i]
            if sum > max:
                max = sum
            if sum <= 0:
                sum = 0
            i += 1
        return max

执行结果

执行结果 : 通过
执行用时 : 40 ms, 在所有 Python3 提交中击败了98.80%的用户
内存消耗 : 13.9 MB, 在所有 Python3 提交中击败了36.33%的用户
在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n),
    我们只遍历了包含有 n 个元素的列表一次。

  • 空间复杂度:O(1),
    所需的额外空间为常数级。

贪心算法

算法实现

class Solution:
    def maxSubArray(self, nums: 'List[int]') -> '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

执行结果

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n),
    我们只遍历了包含有 n 个元素的列表一次。

  • 空间复杂度:O(1),
    所需的额外空间为常数级。

动态规划(Kadane 算法)

算法实现

class Solution:
    def maxSubArray(self, nums: 'List[int]') -> 'int':
        n = len(nums)
        max_sum = nums[0]
        for i in range(1, n):
            if nums[i - 1] > 0:
                nums[i] += nums[i - 1] 
            max_sum = max(nums[i], max_sum)

        return max_sum

执行结果

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(n),
    我们只遍历了包含有 n 个元素的列表一次。

  • 空间复杂度:O(1),
    所需的额外空间为常数级。

分治法

算法实现

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: 'List[int]') -> 'int':
        return self.helper(nums, 0, len(nums) - 1)

执行结果

在这里插入图片描述

复杂度分析

  • 时间复杂度:O(N logN)。
    我们只遍历了包含有 n 个元素的列表一次。

  • 空间复杂度:O(logN),
    递归时栈使用的空间。

小结

先按照自己的想法设计,根据当前数字是否大于零以及当前和的情况,来确定是否要累加到当前和上,然后再判断并修改最大和。该思路与分治法很相似,之后学习了分治法,动态规划以及贪心算法的解决方法。

发布了112 篇原创文章 · 获赞 10 · 访问量 2912

猜你喜欢

转载自blog.csdn.net/qq_45556599/article/details/104503551