§1
题目描述
找乘积最大的连续子数组。
nums = [2,3,-2,4]
输出 = 6
§2
思路解析动画文字版
关键不是背模板,而是看懂为什么这题适合动态规划 · 最大最小。
1. 同时记最大积和最小积:乘积里负数会翻身:最小(负)×负 → 变最大。所以同时维护 imax(以当前结尾的最大积)和 imin(最小积)。起点 2:imax=imin=ans=2。
2. ×3 · imax=6:×3(正数):imax=max(3, 2×3)=6,imin=min(3, 2×3)=3。ans 更新到 6。
3. 关键帧 · 遇负数先交换:关键帧:到 -2(负数)→ 先交换 imax 与 imin(因为最小×负 才可能变最大)。交换后 imax=max(-2, 3×-2)=-2,imin=min(-2, 6×-2)=-12。ans 仍 6。
4. ×4 · imax=4:×4(正数):imax=max(4, -2×4)=4,imin=min(4, -12×4)=-48。ans 仍 6。
5. 答案 ans=6:扫完,答案 ans=6,来自子数组 [2,3]。负数被 imin 接住,正数让 imax 增长。
把这句话记住,下次遇到同类题,就能更快选出方向。
迁移阶梯:把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
边界三连:边界三连:极端输入先过一遍。
几个高频追问,记住答法。
§3
参考代码
class Solution: def maxProduct(self, nums): imax = imin = ans = nums[0] for x in nums[1:]: if x < 0: imax, imin = imin, imax imax = max(x, imax * x) imin = min(x, imin * x) ans = max(ans, imax) return ans看懂代码不等于写得出。盖住上面,自己默写一遍试试。卡在哪一行说不清,就点右下角问小欧。
§4
复杂度
- 时间复杂度:O(n),每个核心状态按算法要求处理固定次数
- 空间复杂度:O(1),只保存必要的辅助结构或递归栈
§5
可套用的代码模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
# 动态规划 · 最大最小 通用检查表# 1. 定义状态/指针/容器# 2. 每轮只做一个清晰动作# 3. 更新答案并处理边界§6
易错点
✗ 错误写法:只维护最大值
✓ 正确写法:同时维护最大和最小
负数乘最小可能变最大
✗ 错误写法:遇负数不交换 imax/imin
✓ 正确写法:负数前先 swap,再各自乘
负数让最小变最大、最大变最小,不交换会算错。
✗ 错误写法:imax/imin 初值设 0 或 1
✓ 正确写法:初值都设 nums[0]
子数组非空;设 0/1 会污染第一个元素的积。
§
面试追问把动画讲成自己的话
追问为什么和「最大子数组和 LC53」不同要记两个?
加法没有负负得正;乘法里负数翻转大小,所以同时跟踪最大积和最小积,负数来时互换。
追问遇到 0 怎么办?
0 让乘积归零,相当于从这里切断、重新开始一段。
追问复杂度?
O(n) 时间、O(1) 空间。
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
下一题 · 一维动态规划 10/13
→单词拆分
LeetCode 139 · 中等 · 沿着 一维动态规划 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
299道动画图解
37节语音讲解
28课数据结构
¥0.27折合 / 天
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
¥99 开通年卡 →
想成体系刷透这类套路?去图解算法专题