股票问题| 豆包MarsCode AI 刷题

60 阅读2分钟

要帮助小R计算能够获得的最大利润,我们可以使用动态规划的方法。由于交易存在冷冻期,我们需要跟踪三种状态:

  1. 持有股票状态(hold) :到第i天为止,手上持有股票时的最大利润。
  2. 冻结状态(cooldown) :第i天是卖出股票后的冷冻期,这天不能买入股票。
  3. 不持有股票且非冻结状态(rest) :到第i天为止,手上不持有股票,并且不在冷冻期的最大利润。

以下是算法的具体步骤:

  • 初始化

    • hold[0] = -stocks[0]:第一天买入股票后的利润。
    • cooldown[0] = 0:第一天不可能处于冷冻期。
    • rest[0] = 0:第一天不做任何操作。
  • 状态转移方程

    • hold[i] = max(hold[i-1], rest[i-1] - stocks[i]):继续持有股票或者今天买入股票。
    • cooldown[i] = hold[i-1] + stocks[i]:昨天持有股票,今天卖出进入冷冻期。
    • rest[i] = max(rest[i-1], cooldown[i-1]):昨天是休息或者昨天是冷冻期,今天继续休息。
  • 结果

    • 最后的最大利润是max(rest[-1], cooldown[-1]),因为最后一天手上不应持有股票。

下面是实现代码:

python
复制代码
def max_profit(stocks):
    if not stocks:
        return 0

    n = len(stocks)
    hold = [0] * n  # 持有股票
    rest = [0] * n  # 休息状态
    cooldown = [0] * n  # 冷冻期

    hold[0] = -stocks[0]
    rest[0] = 0
    cooldown[0] = 0

    for i in range(1, n):
        hold[i] = max(hold[i - 1], rest[i - 1] - stocks[i])
        cooldown[i] = hold[i - 1] + stocks[i]
        rest[i] = max(rest[i - 1], cooldown[i - 1])

    return max(rest[-1], cooldown[-1])

# 测试样例
print(max_profit([1, 2]))           # 输出:1
print(max_profit([2, 1]))           # 输出:0
print(max_profit([1, 2, 3, 0, 2]))  # 输出:3
print(max_profit([2, 3, 4, 5, 6, 7]))  # 输出:5
print(max_profit([1, 6, 2, 7, 13, 2, 8]))  # 输出:12

解释

  • 样例1:在第1天买入,第二天卖出,利润为1
  • 样例2:股票价格下降,不进行任何交易,利润为0
  • 样例3:在第1天买入,第3天卖出,利润为2。然后在第4天休息(冷冻期),第5天再买入并卖出,累计利润为3
  • 样例4:每天价格上涨,买入后一直持有到最后一天卖出,利润为5
  • 样例5:通过多次买卖,在遵守冷冻期规则的情况下,获得最大利润12

总结

  • 通过动态规划,我们有效地考虑了交易中的各种状态和规则。
  • 这种方法的时间复杂度为O(n),空间复杂度为O(n),其中n是股票价格列表的长度。