【Classic 150 刷题计划】 LeetCode 123. 买卖股票的最佳时机 III | C++ 状态机动态规划与通用交易拓展

LeetCode 123. 买卖股票的最佳时机 III

📌 题目描述

题目级别:困难

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

  • 示例 1:
    输入:prices = [3,3,5,0,0,3,1,4]
    输出:6
    解释:在第 4 天(股票价格 = 0)买入,在第 6 天(股票价格 = 3)卖出,利润 = 3-0 = 3 。随后在第 7 天(股票价格 = 1)买入,在第 8 天 (股票价格 = 4)卖出,利润 = 4-1 = 3 。
  • 示例 2:
    输入:prices = [1,2,3,4,5]
    输出:4
    解释:在第 1 天买入,第 5 天卖出,利润 = 4。
  • 示例 3:
    输入:prices = [7,6,4,3,1]
    输出:0
    解释:在这个情况下,没有交易完成,所以最大利润为 0。
  • 提示:
    • 1 <= prices.length <= 10^5
    • 0 <= prices[i] <= 10^5

💡 破题思路:状态机 DP (Finite State Machine DP)

这道题是整个股票交易问题家族的"分水岭"。通过维护交易轮次 kkk持仓状态(持有 / 未持有),可以建立状态机转移。

1. 状态定义

设在第 iii 天结束时:

  • buy[j]:当前完成了 jjj 次买入动作、且手头持有股票时的最大资金收益。
  • sell[j]:当前完成了 jjj 次卖出动作、且手头空仓时的最大资金收益。

2. 状态转移方程

对于每天的股价 price,第 jjj 次交易的状态更新如下:

  • 进入持仓状态 buy[j]
    可以选择继续保持昨天的持仓 buy[j],也可以在上一次卖出空仓 sell[j - 1] 的基础上按今天价格买入:
    buyj=max⁡(buyj,sellj−1−price)buyj = \max(buyj, sellj - 1 - price)buyj=max(buyj,sellj−1−price)
  • 进入空仓状态 sell[j]
    可以选择继续保持昨天的空仓 sell[j],也可以在当前持仓 buy[j] 的基础上按今天价格卖出:
    sellj=max⁡(sellj,buyj+price)sellj = \max(sellj, buyj + price)sellj=max(sellj,buyj+price)

3. 初始化细节

  • buy 数组初始化为负无穷大(如 INT_MIN-prices[0]),表示初始时在未产生现金流前无法凭空持有股票。
  • sell 数组初始化为 0,表示还没开始交易时本金利润为 0。
  • 这种向量化的写法天生具备高度通用性 ,只需将 k=2k = 2k=2 改为任意正整数,即可直接无缝 AC 《LeetCode 188. 买卖股票的最佳时机 IV》(最多完成 kkk 笔交易)。

💻 C++ 代码实现 (原汁原味作者版)

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int k = 2;
        // buy[i] 表示完成第 i 次买入且持股时的最大利润
        // sell[i] 表示完成第 i 次卖出且空仓时的最大利润
        vector<int> buy(k + 1, INT_MIN), sell(k + 1, 0);

        for (auto price : prices)
        {
            for (int i = 1; i <= k; i ++ )
            {
                buy[i] = max(buy[i], sell[i - 1] - price);
                sell[i] = max(sell[i], buy[i] + price);
            }
        }
        return sell[k];
    }
};
相关推荐
luj_17683 小时前
生物体如何应对功能击穿?
c语言·开发语言·c++·经验分享·算法
luj_17683 小时前
击穿分析五大关键步骤
开发语言·网络·c++·经验分享·算法
小王C语言3 小时前
cmake教程
c++·cmake
星空3 小时前
Map<String, String>`Map`是接口,不能直接 new
java·前端·算法
安大小万3 小时前
蓝桥杯Dev-C++ 5.11(编译器)使用细节排坑
c++
shirsl3 小时前
算法 Day3-队列 / deque + 链表
数据结构·python·算法·链表
raindayinrain4 小时前
c++并发--原子操作,内存顺序,屏障
c++·原子操作·操作顺序
张小姐的猫4 小时前
【AI大模型接入SDK】 —— SQLite上手
linux·开发语言·c++·人工智能·python·log4j
码流子4 小时前
2026 图像数据标注工具横评:LabelImg / CVAT / Label Studio / X-AnyLabeling / 国产Web平台,到底怎么选?
大数据·人工智能·算法