LeetCode热题(JS版) - 123. 买卖股票的最佳时机 III(Best Time to Buy and Sell Stock III)

170 阅读2分钟

题目描述

给定一个数组prices,它的第i个元素prices[i]表示一支给定股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成两笔交易。

注意:你不能同时参与多笔交易(即,你必须在再次购买前出售掉之前的股票)。

解题思路

我们可以使用动态规划的方法来解决这个问题。

首先,我们定义四个变量:

  • buy1表示第一次买入股票时的最大利润。
  • sell1表示第一次卖出股票时的最大利润。
  • buy2表示第二次买入股票时的最大利润。
  • sell2表示第二次卖出股票时的最大利润。

我们遍历整个价格数组,在每一天,我们更新上述四个变量的值。

具体算法如下:

  1. 初始化buy1buy2为负无穷大,sell1sell2为0。

  2. 对于每一天的价格price[i],我们首先更新buy1sell1

    • buy1 = Math.max(buy1, -price[i]):更新第一次买入股票的最大利润。我们取当前价格的负值与之前的buy1比较,选择较大的那个。
    • sell1 = Math.max(sell1, buy1 + price[i]):更新第一次卖出股票的最大利润。我们将第一次买入股票后获得的利润与之前的sell1比较,选择较大的那个。
  3. 然后,我们更新buy2sell2

    • buy2 = Math.max(buy2, sell1 - price[i]):更新第二次买入股票的最大利润。我们取第一次卖出股票后获得的利润与之前的buy2比较,选择较大的那个。
    • sell2 = Math.max(sell2, buy2 + price[i]):更新第二次卖出股票的最大利润。我们将第二次买入股票后获得的利润与之前的sell2比较,选择较大的那个。
  4. 最后返回sell2,即为最多可以完成两笔交易的最大利润。

代码实现

function maxProfit(prices: number[]): number {
    let buy1 = Number.MIN_SAFE_INTEGER;
    let buy2 = Number.MIN_SAFE_INTEGER;
    let sell1 = 0;
    let sell2 = 0;

    for (let i = 0; i < prices.length; i++) {
        buy1 = Math.max(buy1, -prices[i]);
        sell1 = Math.max(sell1, buy1 + prices[i]);
        buy2 = Math.max(buy2, sell1 - prices[i]);
        sell2 = Math.max(sell2, buy2 + prices[i]);
    }

    return sell2;
}

复杂度分析

  • 时间复杂度:O(n),其中n是价格数组的长度。我们只需遍历一次价格数组。
  • 空间复杂度:O(1)。我们只使用了常数个额外变量。