题目描述
思路解析动画文字版
下面 16 步动画会按主解代码推进,而不是泛泛讲题型。
1. 读题:最多两笔交易:价格序列是 [3,2,6,5,0,3],最多完成两笔交易,求最大总利润。答案是 7(买 2 卖 6 赚 4,再买 0 卖 3 赚 3)。
2. 四个状态变量:用四个状态滚动:买1=已第一次买入后的最大收益,卖1=已第一次卖出,买2=已第二次买入,卖2=已第二次卖出(即答案)。
3. 初始化:开局:买1=买2=-∞(还没买入,持股收益设为负无穷),卖1=卖2=0(没交易时利润为 0)。下面逐天更新。
4. 第1天 p=3:更新买1:第1天价格 3:买1 = max(-∞, -3) = -3,表示此刻第一次买入,手里成本是 -3。
5. 第1天 p=3:更新卖1/买2/卖2:同一天链式更新:卖1 = max(0, 买1+3) = 0,买2 = max(-∞, 卖1-3) = -3,卖2 = max(0, 买2+3) = 0。第1天利润仍为 0。
6. 第2天 p=2:更新买1:第2天价格 2:买1 = max(-3, -2) = -2,改在更便宜的 2 买入更划算,成本降到 -2。
7. 第2天 p=2:卖1/买2/卖2:卖1 = max(0, 买1+2) = 0,买2 = max(-3, 卖1-2) = -2,卖2 = max(0, 买2+2) = 0。还没卖出,利润仍为 0。
8. 第3天 p=6:买1 不变:第3天价格 6:买1 = max(-2, -6) = -2,在 6 买入更贵,所以保留之前 -2 的成本不变。
9. 第3天 p=6:卖1 赚 4:卖1 = max(0, 买1+6) = max(0, -2+6) = 4:第一笔买 2 卖 6,第一次交易利润达到 4。
10. 第3天 p=6:买2/卖2:买2 = max(-2, 卖1-6) = -2(用第一笔利润 4 抵掉再买的 6);卖2 = max(0, 买2+6) = 4,总利润现在是 4。
11. 第4天 p=5:维持现状:第4天价格 5:买1=-2、卖1=4 维持不变;买2 = max(-2, 卖1-5) = -1 抬高了一点,卖2 = max(4, 买2+5) = 4,总利润仍是 4。
12. 第5天 p=0:买1/买2 抄底:第5天价格 0:买1 = max(-2, -0) = 0(白菜价买入);买2 = max(-1, 卖1-0) = 4,相当于拿第一笔的 4 利润再次免费持仓。
13. 第5天 p=0:卖1/卖2 不变:在 0 卖出不划算:卖1 = max(4, 买1+0) = 4,卖2 = max(4, 买2+0) = 4,都保持 4 不变。
14. 第6天 p=3:卖2 收尾:第6天价格 3:卖2 = max(4, 买2+3) = max(4, 4+3) = 7。第二笔买 0 卖 3 再赚 3,总利润升到 7。
15. 返回答案:遍历结束,返回卖2 = 7:两笔交易(买2卖6 + 买0卖3)合计最大利润 7,正好对应示例答案。
16. 为什么链式更新成立:关键:买2 = max(买2, 卖1-p),第二次买入必须用第一次卖出后的状态卖1,因此两笔交易天然不会重叠,同一天先算买1再算卖2也不会越界。
记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
参考代码
class Solution: def maxProfit(self, prices): buy1 = buy2 = -10**18 sell1 = sell2 = 0 for p in prices: buy1 = max(buy1, -p) sell1 = max(sell1, buy1 + p) buy2 = max(buy2, sell1 - p) sell2 = max(sell2, buy2 + p) return sell2复杂度
- 时间复杂度:O(n),每个价格更新四个状态
- 空间复杂度:O(1),四个变量
易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
地下城游戏
LeetCode 174 · 困难 · 沿着 动态规划套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题