LeetCode 第53题:最大子数组和

66 阅读3分钟

LeetCode 第53题:最大子数组和

题目描述

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

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

难度

中等

题目链接

点击在LeetCode中查看题目

示例

示例 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 解释:连续子数组 [5,4,-1,7,8] 的和最大,为 23 。

提示

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4

解题思路

动态规划(Kadane算法)

这是一道经典的动态规划问题,可以使用Kadane算法在O(n)时间内解决。

关键点:

  1. 维护一个局部最大和和全局最大和
  2. 对于每个元素,可以选择加入前面的子数组或开始新的子数组
  3. 利用动态规划思想优化计算过程
  4. 注意处理全负数的情况

具体步骤:

  1. 初始化局部最大和和全局最大和为第一个元素
  2. 遍历数组,对于每个元素:
    • 计算加入当前元素的新局部最大和
    • 更新全局最大和
  3. 返回全局最大和

图解思路

算法步骤分析表

步骤当前元素局部最大和全局最大和说明
初始-2-2-2第一个元素
第1步111重新开始
第2步-3-21保持原有结果
第3步444重新开始
第4步-134继续累加
第5步255继续累加
第6步166继续累加

状态/情况分析表

情况输入输出说明
单元素[1]1最简单情况
全正数[1,2,3]6全部累加
有负数[-2,1,-3,4]4需要选择

代码实现

C# 实现

public class Solution {
    public int MaxSubArray(int[] nums) {
        // 处理边界情况
        if (nums == null || nums.Length == 0) return 0;
        
        int localMax = nums[0];
        int globalMax = nums[0];
        
        // 从第二个元素开始遍历
        for (int i = 1; i < nums.Length; i++) {
            // 计算当前位置的局部最大和
            localMax = Math.Max(nums[i], localMax + nums[i]);
            // 更新全局最大和
            globalMax = Math.Max(globalMax, localMax);
        }
        
        return globalMax;
    }
}

执行结果

  • 执行用时:284 ms
  • 内存消耗:48.9 MB

代码亮点

  1. 🎯 使用Kadane算法优化性能
  2. 💡 空间复杂度为O(1)
  3. 🔍 代码简洁易懂
  4. 🎨 优雅处理边界情况

常见错误分析

  1. 🚫 没有正确处理负数情况
  2. 🚫 局部最大和计算错误
  3. 🚫 忘记更新全局最大和
  4. 🚫 边界条件处理不当

解法对比

解法时间复杂度空间复杂度优点缺点
暴力枚举O(n²)O(1)直观简单效率低
分治法O(nlogn)O(logn)可并行较复杂
Kadane算法O(n)O(1)最优性能不易理解

相关题目