返回

剖析 LeetCode 第 122 题:“买卖股票的最佳时机 II”

IOS

动态规划解题之道:LeetCode 122 号问题“买卖股票的最佳时机 II”

在瞬息万变的技术领域,掌握解决算法问题的能力至关重要。LeetCode 作为算法练习的知名平台,提供了众多挑战性题目,其中第 122 题“买卖股票的最佳时机 II”便是颇具代表性的一道。

问题

LeetCode 第 122 题“买卖股票的最佳时机 II”要求我们找到在给定的股票价格序列中进行买卖操作以获得最大利润的最佳策略。与第 121 题不同,这道题目允许我们进行多次买卖操作。

解决思路

解决此类问题的经典方法是采用动态规划。动态规划是一种将问题分解成子问题,并存储子问题的最优解以避免重复计算的技术。在解决本题时,我们可以将股票价格序列拆分为若干个子区间,每个子区间代表一次买卖操作的机会。

动态规划解法

定义状态 dp[i][j] 表示在第 i 天持有 j 股股票所能获得的最大利润。其中,i 取值范围为 [0, n-1],表示股票价格序列中的天数;j 取值范围为 [0, 1],表示当前是否持有股票。

动态规划的转移方程为:

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])

其中:

  • dp[i-1][0] 表示第 i-1 天不持有股票的最大利润
  • dp[i-1][1] 表示第 i-1 天持有股票的最大利润
  • prices[i] 表示第 i 天的股票价格

初始化:

  • dp[0][0] = 0(第 0 天不持有股票,利润为 0)
  • dp[0][1] = -prices[0](第 0 天持有股票,利润为 -prices[0])

边界条件:

  • dp[i][0] = max(dp[i-1][0], 0)(第 i 天不持有股票,利润要么延续前一天,要么清零)
  • dp[i][1] = max(dp[i-1][1], -prices[i])(第 i 天持有股票,利润要么延续前一天,要么买入新股票)

代码示例

def maxProfit(prices):
  n = len(prices)
  dp = [[0] * 2 for _ in range(n)]
  dp[0][0] = 0
  dp[0][1] = -prices[0]
  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])
  return dp[n-1][0]

总结

通过本文对 LeetCode 第 122 题“买卖股票的最佳时机 II”的详细剖析,我们深入理解了动态规划在解决算法问题中的强大作用。通过分解问题、存储子问题最优解以及构建转移方程,我们能够高效地求解复杂问题。

掌握动态规划技术不仅可以帮助您解决 LeetCode 等算法练习平台上的难题,更重要的是,它可以培养您对问题的分析和解决能力,这在实际工作中至关重要。

常见问题解答

  • 为什么不持有股票时的利润可以为 0?

因为不持有股票时,我们没有获得任何利润。

  • 为什么持有股票时的利润可以为负?

因为我们可能在股票价格较高时买入,而在股票价格较低时卖出,导致亏损。

  • 动态规划的时间复杂度是多少?

动态规划的时间复杂度为 O(n),其中 n 为股票价格序列的长度。

  • 动态规划的空间复杂度是多少?

动态规划的空间复杂度为 O(n),因为我们只存储 n 个子问题的最优解。

  • 还有其他解决这个问题的方法吗?

还有其他方法,例如贪心算法,但动态规划方法是最有效率的。