力扣53——最大子数组和(Python)

【题目要求】

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

子数组 是数组中的一个连续部分。

示例 1:

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

示例 2: 

输入:nums = [1]
输出:1

示例 3: 

输入:nums = [5,4,-1,7,8]
输出:23

【解题思路】

核心观念:编程实际上是用计算机实现人工能干的事情。
因此解题可以遵循“人工推导——从个体到群体——从特殊到普遍”的思路,即从个例推出通解。
这道题的处理需要稍微灵活点,拿[-2, 1, -3, 4, -1, 2, 1, -5, 4]为例,如果我们人工来做,似乎一时间也没啥头绪。。但是凭借经验,至少我们可以知道,如果一个数组中的元素都是正数,显然最大和连续子数组就是它本身,也就是说我们要尽可能多地把正数放到最后要求的子数组中。那么我们常规遍历一遍数组:

R1:首先拿出-2,由于这是第一个数字,手头上拿出来的没有其他数字了,所以目前最大是-2

R2:接着拿出1,可以发现,[-2, 1]这个子数组的和是-1,比R1的最大结果要大,但是,如果我们只拿1,
    把前面的-2丢掉,是不是更大了,-2<(-2+1)<1,那此时最大和子数组应该是[1]

R3:拿出-3,如果放到前面的最大和子数组中变成[1, -3]显然结果更小了,所以最大子数组还是[1]

R4:继续拿出4,显然单是一个4就比前面的最大和子数组[1]要大了,这时候得想想,能不能让1和4加到一起        
    呢,毕竟1+4=5,只要两者中间的元素不捣乱,那最大值就又能变大了,那我们再考虑把之前丢掉的-3拿 
    回来,组成[1, -3, 4],和为2,显然现在max更新成[4],4前面的元素都得丢掉,毕竟加上了结果反而 
    更小

R5:接下来拿出-1,显然-1<4,最大和子数组为[4],继续遍历

R6:拿出2,2<4,最大和子数组是[4],但是这时候还是得想想,能不能让4和2加到一起呢,如果二者中间的
    元素识相,那最大值就又变大了,那我们再考虑把之前丢掉的-1拿回来组成[4, -1, 2],和为5,显然现 
    在max更新成[4, -1, 2],虽然二者中间的不是正数,但是组合起来的子数组和还是变大了一丢丢的

R7:当前拿出来的是1,是个正数,显然加上去max可以更新为[4, -1, 2, 1]

R8:接下来拿出-5,前面的值加上-5就变小了,所以最大和子数组不变

R9:最后一个是4,考虑一下能不能让4也加进去呢,但因为是连续子数组,所以还得把前面的-5也加上,子数组变成[4, -1, 2, 1, -5, 4],比原先的最大和子数组要小,那么到这里,遍历完数组之后,结果就是[4, -1, 2, 1],值为6。有没有发现,上述的过程中我们一直在考虑当前遍历到一个元素时,到底需不需要把该元素之前的最大值加进去,但是由于是连续子数组,还需考虑当前值和当前值之前最大值二者之间的元素,比如遍历到4的时候,考虑要不要加上前面的最大值1,但是连续子数组就变成了[1, -3, 4],更小了,所以不需要加上之前的值,那么转换成代码可以写成:

【运行代码】

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 定义prev用于存储当前元素之前的最大值
        prev = 0
        # 初始化结果变量
        res = -int(1e9)
        # 遍历数组
        for li in nums:
            # 每次更新当前元素及其之前的最大值,这里可以拿实例手动推导一下,会发现跟前面的推导
            # 流程是一样的,这里的max(prev+li, li)就是实现了每次考虑是否加上前面的最大值,但是
            # 同时还需要加上二者之间的元素,比如遍历到4,前面最大的元素是1, 由于上一步遍历到-3
            # 时,最大值是1-3=-2,所以此时的prev是-2,那显然max(-2+4, 4)结果为4
            prev = max(prev+li, li)
            # 更新最大结果
            res = max(res, prev)
        return res

【运行结果】

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值