LeeCode每日一题--最大子序和

  【前言】坚持日更LeeCode刷题系列

    不积跬步,无以至千里;不积小流,无以成江海。愿与诸君共勉!


  【题目】53.最大子序和

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


    示例:

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

    进阶:

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


    思路一:定义变量num_sum来进行子序和的操作,那么nums[i]小于0的元素什么时候才被考虑进呢?很显然,只有当前面出现的子序和不小于0时,此时才考虑加入负数保证连续且总体和变大的性质。因此,当num_sum为0并且nums[i]<0时,我们跳过该数字;否则不管该数字的正负性都需要加上该数字,并且将此时的num_sum和num_max中的大值赋值给num_max,如果出现num_sum<0,则说明该段子序列不符合条件,则将num_sum赋值为0,即回到最初的情况。没懂的话,可以直接看代码,能够有更加直观的感受。具体代码如下:

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        num_max = max(nums)
        num_sum = 0
        for i in range(len(nums)):
            if(num_sum==0 and nums[i]<0): #跳过此时的所有负数
                continue
            else:
                num_sum = num_sum+nums[i]
                if num_max < num_sum:
                    num_max = num_sum #每一步都得到最大值
                if num_sum<0:    #即前面的序列和小于0,不符合条件,因此赋值为0,相当于回到最初的情况
                    num_sum = 0
        return num_max

    运行结果:
在这里插入图片描述

    思路二:贪心/动态规划(Kadane算法)由于在此题上,两者具有相似性,因此将两者作为一种思路。让我先上一张图:
在这里插入图片描述
    我们进行一次循环,对每个元素寻找在其位置上可以得到的最大值,例如:在[-2,1,-3]中,由于‘1’位置前是‘-2’,则在该位置的最大值为‘1’,同理对于‘-3’而言,他只要考虑前一个位置对其是否有影响。并且在整个遍历的过程中将得到的最大值保留下来,即可得到最大和。具体代码如下:

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

    运行结果:
在这里插入图片描述

    思路三:分治法。想了解的朋友可以通过下方链接查询。

    算法详解


    分享就到这里了,欢迎大家一起交流讨论。


    注明

    题目来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/remove-element

发布了32 篇原创文章 · 获赞 62 · 访问量 1316

猜你喜欢

转载自blog.csdn.net/Mingw_/article/details/104723908