【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];
    }
};
相关推荐
hetao17338373 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia6263 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan3 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
2601_960356384 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah5 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO95 小时前
指针的算术运算详解
java·数据结构·算法
Coder-magician5 小时前
《代码随想录》刷题打卡day47:并查集-part01
数据结构·算法·图论
垆边人似月.5 小时前
VLAN 资源池(100~200 分档)
数据结构·算法
潼心1412o6 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
星光开发者6 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express