LeetCode 53中等动态规划 · Kadane
最大子数组和 图解题解
这道题到底在问什么
找和最大的连续子数组,返回最大和。
- nums
- [-2,1,-3,4,-1,2,1,-5,4]
- 输出
- 6([4,-1,2,1])
最优解:一步一步想明白
- 3关键不是背模板,而是看懂为什么这题适合动态规划 · Kadane。
- 4cur = 以当前元素结尾的最大子数组和。每步 cur = max(x, cur+x):从 x 重开 或 接前面。best 记全程最大。起点 -2:cur=best=-2。
- 5关键帧:到 1,接前面 -2+1=-1 < 单独 1 → 丢前面、从 1 重开,cur=1,best=1。
- 6到 -3:cur+x=1−3=-2 > 单独 -3 → 接上,cur=-2;best 仍 1。
- 7到 4:前面 cur=-2 拖后腿(-2+4=2 < 4)→ 重开,cur=4,best=4。
- 8到 -1:4−1=3 > -1 → 接上,cur=3;best 仍 4。
- 9到 2:3+2=5 → 接上,cur=5,best 更新到 5。
- 10关键帧:到 1,5+1=6 → cur=6,best=6 = 子数组 [4,-1,2,1] 的和。
- 11到 -5:6−5=1,cur 回落到 1;但 best 守住 6 不变。
- 12到 4:cur=max(4,1+4)=5,best 仍 6。答案 best=6,最大子数组 [4,-1,2,1]。
- 15把这句话记住,下次遇到同类题,就能更快选出方向。
- 20把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
⚠️ 容易写错的地方
✗ 错:遇到负数就立刻断开
✓ 对:看 cur+x 和 x 谁更大
小负数可能仍该接上
✗ 错:全负数时返回 0
✓ 对:best 初始化为 nums[0],至少取一个
子数组非空,全负时答案是最大的那个负数,不是 0。
✗ 错:cur 和 best 混为一谈
✓ 对:cur=以当前结尾的最大,best=全程最大
cur 会回落,best 只增不减;返回的是 best。
完整代码(Python / C++ / Java)
Python
class Solution:
def maxSubArray(self, nums):
cur = best = nums[0]
for x in nums[1:]:
cur = max(x, cur + x)
best = max(best, cur)
return bestC++
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < (int)nums.size(); i++) {
cur = max(nums[i], cur + nums[i]);
best = max(best, cur);
}
return best;
}
};Java
class Solution {
public int maxSubArray(int[] nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < nums.length; i++) {
cur = Math.max(nums[i], cur + nums[i]);
best = Math.max(best, cur);
}
return best;
}
}套路模板 · 动态规划 · Kadane
# 动态规划 · Kadane 通用检查表
# 1. 定义状态/指针/容器
# 2. 每轮只做一个清晰动作
# 3. 更新答案并处理边界class Solution {
public:
int maxSubArray(vector<int>& nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < (int)nums.size(); i++) {
cur = max(nums[i], cur + nums[i]);
best = max(best, cur);
}
return best;
}
};class Solution {
public int maxSubArray(int[] nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < nums.length; i++) {
cur = Math.max(nums[i], cur + nums[i]);
best = Math.max(best, cur);
}
return best;
}
}复杂度
时间复杂度
O(n)
每个核心状态按算法要求处理固定次数
空间复杂度
O(1)
只保存必要的辅助结构或递归栈
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 最大子数组和 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
Kadane 核心一句话?+
cur = max(x, cur+x):前面累计是负担就丢掉重开;ans = max(ans, cur)。
全是负数怎么办?+
答案是最大的单元素(子数组至少一个),所以 ans 初值设第一个元素、不是 0。
和「乘积最大子数组」区别?+
加法只需记最大;乘法因负负得正还要记最小。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。