文章目录
-
- 一、题目说明
- 二、题目考点与思路导图
- [三、方法一:暴力枚举法(Brute Force)](#三、方法一:暴力枚举法(Brute Force))
- [四、方法二:动态规划(Kadane's Algorithm)](#四、方法二:动态规划(Kadane’s Algorithm))
- 总结
📘 题目链接:LeetCode.cn #53 最大子数组和
一、题目说明
题目描述:
给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6。
二、题目考点与思路导图
这是一道经典的动态规划入门题 。
关键要点在于:子数组必须连续 ,且我们要找到其最大和。
思维导图(Mermaid)
最大子数组和
暴力法
枚举所有子数组
计算每个子数组的和
O(n^2) 或 O(n^3)
动态规划(Kadane算法)
当前最大和:maxEndingHere
全局最大和:maxSoFar
num, maxEndingHere + num
n
三、方法一:暴力枚举法(Brute Force)
思路
- 枚举所有可能的连续子数组
[i, j] - 计算每个子数组的和,记录其中的最大值。
图解流程图
是
否
是
否
开始
初始化 maxSum = -∞
遍历 i 从 0 到 n-1
初始化 sum = 0
遍历 j 从 i 到 n-1
sum += nums[j]
更新 maxSum = max(maxSum, sum)
j < n-1?
i < n-1?
返回 maxSum
结束
复杂度分析
- 时间复杂度:O(n²)(两层循环)
- 空间复杂度:O(1)
Java实现
java
public class Solution {
public int maxSubArray(int[] nums) {
int maxSum = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
int sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
maxSum = Math.max(maxSum, sum);
}
}
return maxSum;
}
}
四、方法二:动态规划(Kadane's Algorithm)
思路核心
Kadane算法是这题的最优解法。
对于每个位置 i:
- 要么 加入之前的子数组 (
maxEndingHere + nums[i]) - 要么 从当前元素重新开始 (
nums[i])
递推式如下:
maxEndingHere = max(nums[i], maxEndingHere + nums[i])
maxSoFar = max(maxSoFar, maxEndingHere)
流程图说明
是
否
开始
初始化 maxSoFar = nums[0], maxEndingHere = nums[0]
从 i = 1 遍历到 n-1
maxEndingHere = max(nums[i], maxEndingHere + nums[i])
maxSoFar = max(maxSoFar, maxEndingHere)
i < n-1 ?
返回 maxSoFar
结束
示例演示
假设输入:[-2,1,-3,4,-1,2,1,-5,4]
| i | nums[i] | maxEndingHere 计算 | maxEndingHere | maxSoFar |
|---|---|---|---|---|
| 0 | -2 | 初始值 | -2 | -2 |
| 1 | 1 | max(1, -2+1) = 1 | 1 | 1 |
| 2 | -3 | max(-3,1-3)=-2 | -2 | 1 |
| 3 | 4 | max(4,-2+4)=4 | 4 | 4 |
| 4 | -1 | max(-1,4-1)=3 | 3 | 4 |
| 5 | 2 | max(2,3+2)=5 | 5 | 5 |
| 6 | 1 | max(1,5+1)=6 | 6 | 6 |
| 7 | -5 | max(-5,6-5)=1 | 1 | 6 |
| 8 | 4 | max(4,1+4)=5 | 5 | 6 |
✅ 最终结果:6
Java实现代码
java
public class Solution {
public int maxSubArray(int[] nums) {
int maxSoFar = nums[0];
int maxEndingHere = nums[0];
for (int i = 1; i < nums.length; i++) {
maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
}
时间与空间复杂度分析
| 项目 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 数组仅需一次遍历 |
| 空间复杂度 | O(1) | 常数级辅助变量 |
总结
| 方法 | 思路 | 时间复杂度 | 空间复杂度 | 特点 |
|---|---|---|---|---|
| 暴力法 | 枚举所有子数组 | O(n²) | O(1) | 易理解,效率低 |
| 动态规划 | Kadane算法 | O(n) | O(1) | 最优解,简洁高效 |
| 分治法 | 区间划分 | O(n log n) | O(log n) | 理论有趣,实践略繁琐 |