【LeetCode】123. 买卖股票的最佳时机 III
解题思路
本题要求计算最多完成两次交易的最大股票利润,核心在于动态规划的状态设计。需要维护四个状态变量,分别表示:
-
第一次买入后的最大利润
-
第一次卖出后的最大利润
-
第二次买入后的最大利润
-
第二次卖出后的最大利润
通过遍历价格数组,每日更新这四个状态,最终返回第二次卖出后的利润值(即最大利润)。
关键步骤
-
状态初始化:
-
buy1 = -prices[0]:第一天买入股票,利润为负的股价 -
sell1 = 0:第一天无法卖出,利润为0 -
buy2 = -prices[0]:假设第一天完成第一次交易后再次买入 -
sell2 = 0:第一天无法完成第二次卖出
-
-
遍历更新状态(从第2天开始):
-
更新第一次买入:
buy1 = max(保持前一天状态, 今日买入:-prices[i]) -
更新第一次卖出:
sell1 = max(保持前一天状态, 今日卖出:buy1 + prices[i]) -
更新第二次买入:
buy2 = max(保持前一天状态, 今日买入:sell1 - prices[i])(用第一次卖出利润抵消成本) -
更新第二次卖出:
sell2 = max(保持前一天状态, 今日卖出:buy2 + prices[i])
-
-
终止条件:遍历完成后返回
sell2(包含0/1/2次交易的最大值)。
代码实现
代码解析:
-
初始化:处理边界情况(数组长度≤1),并设置初始状态。
-
状态更新:
-
第一次买入:比较“保持之前买入状态”与“今日买入”的成本,取最小值(负值最大)。
-
第一次卖出:比较“保持之前卖出状态”与“今日卖出”的利润(买入成本+当前价格)。
-
第二次买入:用第一次卖出的利润抵消当前股价成本。
-
第二次卖出:第二次买入成本加上当前价格。
-
-
返回值:
sell2天然包含0~2次交易的最大值(例如全跌时返回0)。
示例测试
复杂度分析
|
维度 |
结果 |
说明 |
|---|---|---|
|
时间复杂度 |
O(n) |
遍历数组一次,n为数组长度 |
|
空间复杂度 |
O(1) |
仅使用4个常量存储状态变量 |
关键点总结
-
状态设计:
-
四个状态变量覆盖两次交易的完整生命周期(买入→卖出→再买入→再卖出)。
-
状态转移依赖前一日状态与当日操作的组合。
-
-
初始化逻辑:
-
buy2初始化为-prices[0]是关键,表示“第一天完成第一次交易后立即买入第二次”。
-
-
贪心与动态规划的融合:
-
每次更新状态时,都选择局部最优解(如买入成本最低、卖出利润最高),最终得到全局最优。
-
-
边界处理:
-
数组长度≤1时直接返回0。
-
全下跌行情时,
sell2能正确返回0(通过max函数保证不出现负利润)。
-
-
与单次交易的差异:
-
单次交易只需维护
buy和sell,而两次交易需扩展为四个状态,且第二次买入依赖第一次卖出的利润。
-

浙公网安备 33010602011771号