LeetCode 第53题:最大子数组和
题目描述
给你一个整数数组 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 解释:连续子数组 [5,4,-1,7,8] 的和最大,为 23 。
提示
1 <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4
解题思路
动态规划(Kadane算法)
这是一道经典的动态规划问题,可以使用Kadane算法在O(n)时间内解决。
关键点:
- 维护一个局部最大和和全局最大和
- 对于每个元素,可以选择加入前面的子数组或开始新的子数组
- 利用动态规划思想优化计算过程
- 注意处理全负数的情况
具体步骤:
- 初始化局部最大和和全局最大和为第一个元素
- 遍历数组,对于每个元素:
- 计算加入当前元素的新局部最大和
- 更新全局最大和
- 返回全局最大和
图解思路
算法步骤分析表
| 步骤 | 当前元素 | 局部最大和 | 全局最大和 | 说明 |
|---|---|---|---|---|
| 初始 | -2 | -2 | -2 | 第一个元素 |
| 第1步 | 1 | 1 | 1 | 重新开始 |
| 第2步 | -3 | -2 | 1 | 保持原有结果 |
| 第3步 | 4 | 4 | 4 | 重新开始 |
| 第4步 | -1 | 3 | 4 | 继续累加 |
| 第5步 | 2 | 5 | 5 | 继续累加 |
| 第6步 | 1 | 6 | 6 | 继续累加 |
状态/情况分析表
| 情况 | 输入 | 输出 | 说明 |
|---|---|---|---|
| 单元素 | [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
代码亮点
- 🎯 使用Kadane算法优化性能
- 💡 空间复杂度为O(1)
- 🔍 代码简洁易懂
- 🎨 优雅处理边界情况
常见错误分析
- 🚫 没有正确处理负数情况
- 🚫 局部最大和计算错误
- 🚫 忘记更新全局最大和
- 🚫 边界条件处理不当
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 暴力枚举 | O(n²) | O(1) | 直观简单 | 效率低 |
| 分治法 | O(nlogn) | O(logn) | 可并行 | 较复杂 |
| Kadane算法 | O(n) | O(1) | 最优性能 | 不易理解 |