【力扣-53. 最大子数组和 ✨】Python笔记

24 阅读2分钟

一、前置核心知识点:贪心算法

1. 贪心算法定义

在每一步做出当前最优选择,从而希望得到全局最优解。核心思想是:局部最优 → 全局最优

2. 适用场景

问题可分解为若干子问题,且每个子问题的最优解能组合成全局最优解。

3. 贪心算法步骤

  1. 将问题分解为若干子问题
  2. 找出适合的贪心策略
  3. 求解每一个子问题的最优解
  4. 将局部最优解堆叠成全局最优解

二、经典算法题:最大子数组和(LeetCode 53)

题目描述

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

示例

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

最优解法:贪心算法

核心思路

遍历数组时,维护当前连续子数组和

  • 如果当前累计和 current_sum < 0,说明它对后续元素是 “拖累”,直接抛弃之前的子数组,从当前元素重新开始累计。
  • 如果当前累计和 > 0,则继续累加。
  • 同时维护一个 max_sum 记录遍历过程中出现的最大和。

代码实现

from typing import List 
class Solution: 
    def maxSubArray(self, nums: List[int]) -> int:
        if not nums: 
            return 0 
            
        current_sum = 0 
        max_sum = nums[0] # 初始化为第一个元素,避免全负数场景 
        
        for num in nums: 
            # 如果当前累计和为负,重置为0,从当前元素重新开始 
            if current_sum < 0: 
                current_sum = 0 
                
            current_sum += num 
            
            # 更新最大和
            if current_sum > max_sum:
                max_sum = current_sum 
                
        return max_sum

三、关键逻辑详解

1. 核心判断

if current_sum < 0: current_sum = 0

  • 当之前的累计和为负数时,它会拉低后续元素的和,因此抛弃它,从当前元素重新开始更优。
  • 例如:[-2, 1] 中,-2 是拖累,直接重置为 0,再 +1 得到 1,比 -2+1=-1 更大。

2. 边界处理

  • 初始化 max_sum = nums[0],避免数组全为负数时返回 0
  • 例如:nums = [-1, -2, -3],最大子数组和为 -1

3. 复杂度分析

  • 时间复杂度:O (n),仅遍历一次数组。
  • 空间复杂度:O (1),仅使用常数额外空间。

四、算法对比与拓展

1. 与动态规划对比

  • 贪心解法:O (n) 时间 + O (1) 空间,更高效。
  • 动态规划:dp[i] = max(nums[i], dp[i-1]+nums[i]),思路类似但空间复杂度稍高。

2. 拓展场景

  • 最小子数组和:将贪心逻辑反转,维护最小和。
  • 最长连续子数组:在贪心基础上记录子数组起止索引。