【前言】坚持日更LeetCode刷题系列
不积跬步,无以至千里;不积小流,无以成江海。愿与诸君共勉!
【题目】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