返回

算法爬坑:股票买卖含手续费最佳时机探索

前端

作为一名JavaScript算法爱好者,我踏上了LeetCode刷题的征程。其中,一道名为"买卖股票的最佳时机含手续费"的题目,让我在算法的道路上留下了一条蜿蜒的爬坑印记。

问题

给定一个股票价格数组 prices 和一个手续费 fee。我们可以在任何时间点买入或卖出一股股票。求在给定的手续费下,买卖股票所能获得的最大收益。

算法设计

解决此题的关键在于建立一个状态转移方程。记 dp[i][j] 为持有 j 股股票到第 i 天为止的最大收益。则状态转移方程为:

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

其中:

  • dp[i][0] 表示第 i 天持有0股股票的最大收益
  • dp[i][1] 表示第 i 天持有1股股票的最大收益

代码示例

const maxProfit = (prices, fee) => {
  if (!prices || prices.length === 0) return 0;
  const n = prices.length;
  const dp = Array(n).fill(0).map(() => Array(2).fill(0));
  dp[0][0] = 0;
  dp[0][1] = -prices[0];
  for (let i = 1; i < n; i++) {
    dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);
    dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i] - fee);
  }
  return dp[n-1][0];
};

代码解读

代码中,dp 数组记录了到第 i 天为止,持有不同数量股票的最大收益。

  • dp[i][0] 表示第 i 天持有 0 股股票的最大收益,它要么来自于前一天持有 0 股股票,要么来自于前一天持有 1 股股票并在第 i 天卖出。
  • dp[i][1] 表示第 i 天持有 1 股股票的最大收益,它要么来自于前一天持有 1 股股票,要么来自于前一天持有 0 股股票并在第 i 天买入。

陷阱与收获

在解决这道题目时,我经历了以下陷阱:

  • 忘记考虑手续费: 起初,我忽略了手续费的影响,导致结果不正确。
  • 状态定义错误: 一开始,我将状态定义为是否持有股票,而不是持有股票的数量,导致状态转移方程复杂且容易出错。

通过解决这道题目,我收获了以下经验:

  • 细致分析问题: 在解决算法问题时,必须仔细分析问题,考虑所有可能的情况。
  • 优化状态转移方程: 通过仔细考虑问题,可以优化状态转移方程,提高代码效率和可读性。
  • 善于利用数组: 数组可以存储状态转移过程中的中间结果,简化代码逻辑。