【leecode】第53题:最大子序和

本文介绍了如何使用贪心法和动态规划解决LeetCode上的最大子序和问题。详细解析了两种方法的解题思路,包括当数组元素全为正、负或混合时的最大子序和情况,并给出了相应的Python代码实现。此外,还探讨了更简洁的解决方案,虽然效率略低但思路融合了贪心与动态规划的特点。
摘要由CSDN通过智能技术生成

  题目:

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

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

题目链接:最大自序和


题目限制:

时间复杂度为O(n)


解题思路:

子序和由连续数组组成

子数组最少包含一个元素


数组边界:

当数组元素全为整数时,数组和即为最大子序和

当数组元素全为负数时,数组元素最大值即为最大子序和

当数组同时存在正负数时,最大子序和的连续数组必定以正数开始

当最大子序和小于数组元素最大值时,数组元素最大值即为最大子序和


实现代码:

测试数组nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]

通过测试结果[4, -1, 2, 1],反推编码执行过程

贪心法

# 贪心法
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        sum, result = 0, float("-inf")          # float('-inf') 正负无穷的意思
        for i in range(len(nums)):              # 遍历nums
            sum += nums[i]                      # 数组元素相加
            result = max(result, sum)           # 取最大值
            if (sum < 0):                       # 丢弃小于0的子序和
                sum = 0
        return result

贪心法的核心逻辑:若当前指针所指元素之前的和小于0,则丢弃当前元素之前的数列

一边遍历,一边计算子序和,当子序和相加为负数时,丢弃该子序和

截取官方视频解说的片段

 

 由解题思路可知, 最大子序和需正数开始,通过一边遍历,一边对比当前和和最大和的值

 动态规划

# 动态规划
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1, len(nums)):           # 由return 返回结构可知,当数组元素只有一个时,无需对比
            if nums[i - 1] > 0:                 # 最大子序和条件
                nums[i] += nums[i - 1]          # 计算该组子序和
        return max(nums)                        # 取最大的子序和

动态规划的核心逻辑:若前一个元素大于0,则将其加到当前元素上

一边遍历,一边计算正数开始的子序和,最后返回最大的子序和

截取官方视频解说的片段

 更简洁的方法

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

nums[i - 1] 是第 i - 1 个元素

max(nums[i - 1] ,0)是与0对比 i元素前最大的元素

该代码的运行逻辑和通过贪心法和动态规划的思路结合在一起

该代码的缺点就是会比动态规划运行得更慢,因为执行了两次max()函数


结论:

该题主要难点是考察是否可理清找到最大子序和的逻辑思路

max()内置函数的深入应用

动态规划的基础使用


LeetCode相关数组题:

【leecode】第35题:搜索插入位置_inganxu-CSDN博客

【leecode】第27题:移除元素_inganxu-CSDN博客

【leecode】第1题:两数之和_inganxu-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

inganxu

感谢您的支持!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值