LeetCode 53, Maximum Subarray, 求数组和最大的子序列

Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example 1:

Input: [-2, 1, -3, 4, -1, 2, 1, -5, 4],
Output: 6
Explanation: [4, -1, 2, 1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

分析:

该题目使用Kadane算法可以很容易得到O(n)的时间复杂度。算法解析如下:

在数组遍历之前,设置两个变量maxSum初始化为负无穷,用来标记全局最大和;curMax初始化为0,用来记录当前循环的局部最大和。在遍历的过程中,如果curMax > maxSum则对全局的变量进行更新,否则不更新。那么遍历结束,得到的一定是全局的局部最大和。为什么是该值是全局最大,有如下分析:

假设当前数组循环为i,如果此时curMax是一个负数,那么进行i+1次循环的时候,就不需要将其相加,因为相加的结果一定使和sum变得更小,这不是我们求最大和想看到的。此时便可以将curMax置0,下一次循环开始重复这个过程(我刚开始不接受这种设定,中间的数和后面的数加起来是否有可能更大?)。我给不了数学上的证明,但是可以从下面图例,感性的分析一下,若有错误,请各位指正:

在这里插入图片描述

在整个循环过程中,curMax可能会经历多次上图的过程。当curMax为正数,可以继续与后面的数相加( x 0 x_0 x0 x m x_m xm的过程)中间出现最大值保存到maxSum中(红色方框所示),当curMax变为负数后,舍弃前面所有的结果,重新计算(因为,curMax的变化如曲线图所示,蓝色虚线后面部分,使curMax有变小的趋势,这不是我们想要得到的,蓝色虚线后面的部分到 x m x_m xm之间的数都不值得与 x m x_m xm后面的数进行累加了)。

方法一和方法二均采用Kadane算法,其实现方式不一样。方法一更易于理解,方法二使用内建函数max(),简化了代码。当判断curMax + aa的大小的时候,显然如果curMax是一个负数,那么返回一定是a.这里就等同于方法一的if判断。

Python3 代码如下:

# 方法一
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        curMax ,maxSum = 0, -float('inf')
        for a in nums:
            if curMax < 0: curMax = 0
            curMax += a
            maxSum = max(maxSum, curMax)
        
        return maxSum

# 方法二
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        curMax, maxSum = 0, -float('inf')
        for a in nums:
            curMax = max(curMax + a, a)
            maxSum = max(maxSum, curMax)
        
        return maxSum
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值