题目描述
思路解析动画文字版
关键不是背模板,而是看懂为什么这题适合状态机 DP。
1. hold=手里有股票时的最大利润:hold[t]=第 t 天结束时「手里持有股票」的最大利润(买入花了钱,所以常是负数或较小)。
2. sold=今天刚卖出:sold[t]=第 t 天「今天刚把股票卖掉」后的利润。卖出当天单独成一态,是为了下一天强制冷冻。
3. rest=空仓休息(已过冷冻):rest[t]=第 t 天「空仓、且不在刚卖出那一瞬」的最大利润,也就是可以自由买入的状态。
4. 买入:rest → hold:第 3 天 hold = max(昨 hold −1, 昨 rest 1 − price 0) = 1 —— 只能从「休息态 rest」花钱买入变成 hold。
5. 卖出:hold → sold:第 4 天 sold = 昨 hold 1 + price 2 = 3 —— 把手里的股票卖掉,从 hold 转到 sold。
6. 冷冻:sold → rest:第 3 天 rest = max(昨 rest 1, 昨 sold 2) = 2 —— 卖出后必须隔一天才能再买,冷冻期就靠「sold 只能转 rest」表达。
7. 每天滚动更新三个状态:每天都用「昨天的三个值」同时算出今天的 hold / sold / rest —— 先把旧值存下来再更新,别互相覆盖。
8. 答案=max(sold, rest):最后一天手里不该还留着股票,所以答案 = max(末日 sold 3, 末日 rest 2) = 3。
把这句话记住,下次遇到同类题,就能更快选出方向。
迁移阶梯:把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
边界三连:边界三连:极端输入先过一遍。
几个高频追问,记住答法。
参考代码
class Solution: def maxProfit(self, prices): hold, sold, rest = -10**9, 0, 0 for p in prices: old_hold, old_sold, old_rest = hold, sold, rest hold = max(old_hold, old_rest - p) sold = old_hold + p rest = max(old_rest, old_sold) return max(sold, rest)复杂度
- 时间复杂度:O(n),每个核心状态按算法要求处理固定次数
- 空间复杂度:O(1),只保存必要的辅助结构或递归栈
可套用的代码模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
# 状态机 DP 通用检查表# 1. 定义状态/指针/容器# 2. 每轮只做一个清晰动作# 3. 更新答案并处理边界易错点
面试追问把动画讲成自己的话
追问为什么用状态机 DP?
追问和普通买卖(LC122)差在哪?
追问复杂度?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
零钱兑换 II
LeetCode 518 · 中等 · 沿着 二维动态规划 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题