【leetcode】188. 买卖股票的最佳时机 IV

66 阅读2分钟

leetcode-188.png 动态规划

var maxProfit = function (k, prices) {
    let n = prices.length
    if (k >= Math.floor(n / 2)) {
        let profit = 0
        for (let i = 1; i < n; ++i) {
            if (prices[i] > prices[i - 1]) {
                profit += (prices[i] - prices[i - 1])
            }
        }
        return profit
    }
    // dp[i][j] 表示第i天进行j次操作获取的最大利润
    let dp = Array.from({ length: n }, () => Array(k + 1).fill(0))
    for (let j = 1; j <= k; ++j) {
        let profit = -prices[0]
        for (let i = 1; i < n; ++i) {
            // 卖出操作
            dp[i][j] = Math.max(dp[i - 1][j], prices[i] + profit)
            // 买入操作
            profit = Math.max(profit, dp[i][j - 1] - prices[i])
        }
    }
    return dp[n - 1][k]
};

18行代码

dp[i][j] = Math.max(dp[i - 1][j], prices[i] + profit)
  • dp[i][j] 表示在第 i 天时,最多允许 j 次交易,能获得的最大利润。

  • 这里我们有两个选择:

    1. 不交易:即保持前一天的最大利润 dp[i-1][j],也就是今天不进行交易。

    2. 卖出股票:假设今天是卖出的一天,那么我们需要加上之前买入时的最大潜在收益 maxProfit,以及今天卖出时的价格 prices[i]。因此利润是 prices[i] + maxProfit

    • maxProfit 表示在之前某一天买入的最大利润(包括买入前的交易次数为 j-1 的最大利润,之后再加上今天的卖出)。

最终,通过 Math.max(dp[i-1][j], prices[i] + profit) 比较选择:

  • 不交易 vs 卖出并获得最大利润。

20行代码

profit = Math.max(profit, dp[i][j - 1] - prices[i])
  • profit 代表在 i 天之前,选择某一天买入股票时,最大可能的潜在利润。
  • dp[i][j-1] 表示在第 i 天之前,最多允许 j-1 次交易时的最大利润。
  • dp[i][j-1] - prices[i] 表示如果在 i 天买入股票时的剩余利润:用 dp[i][j-1] 的值减去当天的价格 prices[i],因为我们需要减去买入股票的成本。
  • 更新 profit 的目的是为了在接下来的日子中找到最佳的买入点,以便后续卖出时能获得最大利润。