这道题是经典的动态规划状态机问题。核心在于处理“冷冻期”卖出股票后你无法在第二天买入股票即冷冻期为 1 天。我们可以通过维护三个状态来解决这个问题。思路解析我们可以定义三种状态持有股票 (hold)当前手里有一支股票。不持有股票处于冷冻期 (cooldown)今天刚卖出股票明天不能买。不持有股票不处于冷冻期 (free)手里没股票且不是刚卖出的可以随时买入。状态转移方程hold 的来源昨天就持有今天休息dp[i-1][hold]昨天是“不持有且非冷冻期”今天买入dp[i-1][free] - prices[i]cooldown 的来源昨天持有今天卖出dp[i-1][hold] prices[i]free 的来源昨天是冷冻期今天解冻dp[i-1][cooldown]昨天就是“不持有且非冷冻期”今天继续休息dp[i-1][free]Java 代码实现为了节省空间我们不需要维护整个二维数组只需要用三个变量滚动更新即可。class Solution {public int maxProfit(int[] prices) {if (prices null || prices.length 2) {return 0;}// 初始化第一天的状态 // hold: 第一天买入收益为 -prices[0] int hold -prices[0]; // cooldown: 第一天不可能卖出收益为 0 int cooldown 0; // free: 第一天不操作收益为 0 int free 0; for (int i 1; i prices.length; i) { // 保存上一轮的状态防止计算过程中被覆盖 int prevHold hold; int prevCooldown cooldown; int prevFree free; // 状态转移 // 1. 今天持有要么昨天就持有要么昨天是 free 状态今天买入 hold Math.max(prevHold, prevFree - prices[i]); // 2. 今天冷冻意味着昨天持有今天卖出了 cooldown prevHold prices[i]; // 3. 今天 free要么昨天是冷冻期今天解冻要么昨天就是 free free Math.max(prevCooldown, prevFree); } // 最后一天手里没股票肯定比手里有股票赚得多或者持平 // 所以取 cooldown 和 free 的最大值 return Math.max(cooldown, free); }}复杂度分析时间复杂度O(N)只需要遍历一次价格数组。空间复杂度O(1)只使用了常数个变量来存储状态。关键点总结冷冻期的处理买入时只能从 free 状态转移过来不能从 cooldown 转移因为 cooldown 的第二天必须继续休息不能买入。最终结果最后一天肯定是“不持有股票”的状态收益最高所以答案是 max(cooldown, free)。需要顺带看看它的变体 LeetCode 122无冷冻期的解法吗对比着看状态机设计会更清晰。