python 简易算法-Leet码-最大子阵

uqxowvwt  于 2023-01-19  发布在  Python
关注(0)|答案(4)|浏览(140)

我很难理解这个。
给定一个整数数组nums,找到具有最大和的连续子数组(至少包含一个数字),并返回其和。
子数组是数组的连续部分。
例一:
输入:数值=[-2,1,-3,4,-1,2,1,-5,4]输出:6说明:[4,-1,2,1]具有最大和= 6。示例2:
输入:数值=[1]输出:1例三:
输入:数值=[5,4,-1,7,8]输出:23

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        subarray1=[]
        subarray2=[]
    
        for n in nums:
            subarray1.append(sum(nums[nums.index(n):]))
            nums2=nums[::-1]
            subarray2.append(sum(nums2[nums.index(n):]))
            para1=subarray1.index(max(subarray1))
            para2=len(nums)-subarray2.index(max(subarray2))
            ans=sum(nums[para1:para2])
        
        if sum(nums)>ans :
            ans=sum(nums)
        
        if len(nums)==2 and sum(nums)< nums[0] or nums[1] :
            ans=max(nums)
       
        return ans

我不懂迭代逻辑,视频中的答案是错误的。我的逻辑是创建一个数组,对两边的输入数组求和,并使用这两个数组上的最大值的索引来计算最大和子数组参数。
我的答案应该是错误的,当复制到leet代码https://leetcode.com/problems/maximum-subarray/
已经尝试了几个小时,它被标记为容易。我相信有一个简单的迭代方式做它,但我已经搜索到的一切都是错误的。

bq3bfh9z

bq3bfh9z1#

对于许多这样的问题,都有一个标准的逻辑,假设你知道nums[:n - 1]是一个具有最大总和的子数组,那么对于nums[:n],你能找到的具有最大总和的子数组是什么?
有两种可能性:

  • 新答案不包含nums[n-1]。在这种情况下,它必须与旧答案相同
  • 新答案 * 不 * 包含nums[n-1]

所以......实际的算法是迭代遍历数组,反复向数组中添加新元素,并跟踪两个答案:
1.总数最大的子数组是什么
1.包含最后一个元素的最大总和的子数组是什么?(这个答案可能和前面的相同。)
当您随后将新元素添加到数组末尾时:
1.具有最大总计的子数组是(a)以前的最大总计,或(b)以前的最大总计(包含最后一个元素加上新的最后一个元素),或(c)只是最后一个元素。选择具有最大总计的子数组。
1.包含最后一个元素的总和最大的子数组是上述(b)或(c)中较大的一个。

4xrmg8kj

4xrmg8kj2#

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

这是具有恒定空间的2遍O(n)时间复杂度解。
工作原理:我们把每个元素加到它的前趋元素上,前提是前趋元素大于0(大于或等于也可以)。如果负数已经设法使它小于0,我们就丢弃前缀,不再关心它们;但如果还有一些正值,我们就加上它,因为它总比没有好。
最后我们寻找最大值。
要使它成为一个循环,你只需有一个best值,在每次迭代时取max,这样你就不需要在数组末尾再次循环取max。
这是顺便说一句,Kadane的算法,如果你有兴趣进一步阅读它。

1aaf6o9v

1aaf6o9v3#

下面是我的解决方案,虽然当输入列表有很多元素时会超过时间限制。我的想法是尝试每个子列表的总和,并相应地更新最大总和。有一个更快,但更复杂的方法是使用“分治”方法:https://leetcode.com/problems/maximum-subarray/discuss/1849465/Divide-and-Conquer-Approach-with-Python
我的解决方案(由于Time Limit Exceeded,适用于200/209种情况):

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        max_sum = - 10 ** 4

        for i in range(len(nums)):
            for j in range(i + 1, len(nums) + 1):
                s = sum(nums[i:j])
                if max_sum < s:
                    max_sum = s
        return max_sum
e4yzc0pl

e4yzc0pl4#

你可以使用Kadane算法在O(n)时间和空间(以及恒定的额外空间)内求解problem,这是一个简单的动态编程算法:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        max_sum = -10**4
        current_sum = 0
        
        for n in nums:
            current_sum = n if n > current_sum+n else current_sum+n
            if current_sum > max_sum:
                max_sum = current_sum
        return max_sum

相关问题