返回

让刷题更轻松:121. 买卖股票的最佳时机

后端

朋友们,欢迎来到「刷题日记」!在今天这篇文章中,我们将一起探索一道经典的算法问题——121. 买卖股票的最佳时机。准备好拿起你的键盘,我们将踏上征服刷题世界的又一段旅程!

问题

让我们从问题开始:

今天我们来做一个简单的问题:假设有这样一个数组,其中第 i 个元素代表第 i 天股票的价格。如果你可以任意多次买卖股票,并且每次交易都需要付手续费,那么你可以获得的最大利润是多少?

注意:你不能同时持有多支股票。

简而言之,我们的目标是找到购买和出售股票的最佳时机,以实现最大的利润。然而,有一个小插曲:我们每次交易都需要支付手续费。

动态规划解决方案

解决此类问题的一个常用策略是动态规划。让我们一步一步地构建一个动态规划解决方案:

1. 定义状态:

我们定义一个状态 dp[i][k],其中:

  • i:当前天数
  • k:剩余交易次数

2. 状态转移方程:

接下来,我们定义状态转移方程,它描述了如何从一个状态转移到另一个状态:

dp[i][k] = max(dp[i-1][k], dp[i-1][k-1] + prices[i] - fee)

这个方程意味着,我们在第 i 天有两种选择:

  • 持有股票: 保持 k 不变,并使用前一天的状态 dp[i-1][k]
  • 出售股票:k 减 1,并将当天股票价格(减去手续费)添加到前一天的状态 dp[i-1][k-1] 中。

3. 边界条件:

我们需要设置一些边界条件来初始化动态规划表:

  • dp[0][k] = 0:第 0 天没有交易。
  • dp[i][0] = -INF:没有剩余交易次数。

4. 计算最大利润:

最后,我们的最大利润存储在 dp[n-1][1] 中,其中 n 是股票价格数组的长度。

代码实现

使用 Python 实现上述动态规划解决方案:

def maxProfit(prices, fee):
    n = len(prices)
    dp = [[0] * 2 for _ in range(n)]
    
    dp[0][1] = -prices[0] - fee
    
    for i in range(1, n):
        dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
        dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i] - fee)
    
    return dp[n-1][0]

总结

通过本文,我们一起探索了「121. 买卖股票的最佳时机」这道经典算法问题。我们深入研究了动态规划解决方案,并提供了详细的代码实现。

记住,刷题是一个不断学习和完善的过程。保持好奇心,继续磨练你的算法技能。期待与你们在下一期的「刷题日记」中再会!