伴学笔记之题解3| 豆包MarsCode AI刷题

53 阅读3分钟

题目解析

本题是经典的动态规划问题,要求我们在遵守以下股票交易规则的情况下,计算出最大化收益:

  1. 可以多次买卖股票;
  2. 买入之前必须先卖出手中持有的股票;
  3. 卖出后有一天冷冻期,在冷冻期内不能买入。

解题思路

1. 动态规划建模

dp[i][state] 表示第 i 天处于某个状态 state 时的最大收益,其中:

  • state = 0 表示不持有股票且不在冷冻期
  • state = 1 表示持有股票
  • state = 2 表示不持有股票且在冷冻期
状态转移方程
  1. 不持有股票且不在冷冻期

    dp[i][0]=max(dp[i1][0],dp[i1][2])dp[i][0] = \max(dp[i-1][0], dp[i-1][2])

    • 第 i 天没有股票且不在冷冻期,可能是前一天也是这种状态,或者从冷冻期结束转换过来。
  2. 持有股票

    dp[i][1]=max(dp[i1][1],dp[i1][0]stocks[i])dp[i][1] = \max(dp[i-1][1], dp[i-1][0] - \text{stocks}[i])

    • 第 i 天持有股票,可能是前一天也持有股票,或者今天买入了股票(从状态 0 转移过来)。
  3. 不持有股票且在冷冻期

    dp[i][2]=dp[i1][1]+stocks[i]dp[i][2] = dp[i-1][1] + \text{stocks}[i]

    • 第 i 天处于冷冻期,必然是前一天卖出了股票。
初始条件
  • 第一天没有股票且不在冷冻期:dp[0][0] = 0;
  • 第一天持有股票:dp[0][1]=stocks[0]dp[0][1] = -\text{stocks}[0](因为买入股票收益为负);
  • 第一天不持有股票且在冷冻期:dp[0][2] = 0。
最终结果

最大收益出现在状态 02 中:

maxprofit=max(dp[n1][0],dp[n1][2])max_{profit} = max(dp[n-1][0], dp[n-1][2])

2. 时间和空间优化

由于 dp[i] 的状态只依赖于 dp[i-1],可以将 O(n)O(n) 的空间复杂度优化为 O(1)O(1)


算法实现

Python 代码

def max_profit(stocks):
    if not stocks or len(stocks) < 2:
        return 0

    # 初始化状态变量
    n = len(stocks)
    hold = -stocks[0]  # 持有股票的状态
    no_stock = 0       # 不持有股票且不在冷冻期
    frozen = 0         # 不持有股票且在冷冻期

    # 动态规划过程
    for i in range(1, n):
        new_no_stock = max(no_stock, frozen)  # 状态 0
        new_hold = max(hold, no_stock - stocks[i])  # 状态 1
        new_frozen = hold + stocks[i]  # 状态 2

        # 更新状态
        no_stock, hold, frozen = new_no_stock, new_hold, new_frozen

    # 返回最终结果
    return max(no_stock, frozen)

# 测试样例
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:stocks=[1,2]\text{stocks} = [1, 2]

  1. 第 1 天买入,收益为 -1;
  2. 第 2 天卖出,收益为 2 - 1 = 1。

最终收益:11。


示例 3:stocks=[1,2,3,0,2]\text{stocks} = [1, 2, 3, 0, 2]

  1. 第 1 天买入,收益为 -1;
  2. 第 2 天卖出,收益为 2 - 1 = 1;
  3. 第 4 天买入,收益为 1 - 0 = 1;
  4. 第 5 天卖出,收益为 2 - 0 = 2。

最终收益:1 + 2 = 3。


复杂度分析

  1. 时间复杂度:O(n),其中 n 是股票价格的天数。

    • 遍历股票价格一次,每天更新三个状态。
  2. 空间复杂度:O(1)。

    • 使用常量级别的变量存储状态。

总结

本题通过动态规划解决,核心在于构建三种状态的转移方程并严格按照规则进行状态更新。这三种状态分别是:持有股票、不持有股票且不在冷冻期、不持有股票且在冷冻期。通过对状态转移方程的优化,我们能够有效减少不必要的重复计算。经过进一步优化,时间复杂度降低到 O(n)O(n),空间复杂度也优化为 O(1)O(1),仅需少量变量存储状态值,从而达到了理想的时间和空间效率。这是经典的股票交易问题之一,在动态规划领域具有很高的学习价值,同时也能很好地帮助我们理解复杂问题的分解与求解。