题目描述
给定一个数组prices,它的第i个元素prices[i]表示一支给定股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成两笔交易。
注意:你不能同时参与多笔交易(即,你必须在再次购买前出售掉之前的股票)。
解题思路
我们可以使用动态规划的方法来解决这个问题。
首先,我们定义四个变量:
buy1表示第一次买入股票时的最大利润。sell1表示第一次卖出股票时的最大利润。buy2表示第二次买入股票时的最大利润。sell2表示第二次卖出股票时的最大利润。
我们遍历整个价格数组,在每一天,我们更新上述四个变量的值。
具体算法如下:
-
初始化
buy1和buy2为负无穷大,sell1和sell2为0。 -
对于每一天的价格
price[i],我们首先更新buy1和sell1:buy1 = Math.max(buy1, -price[i]):更新第一次买入股票的最大利润。我们取当前价格的负值与之前的buy1比较,选择较大的那个。sell1 = Math.max(sell1, buy1 + price[i]):更新第一次卖出股票的最大利润。我们将第一次买入股票后获得的利润与之前的sell1比较,选择较大的那个。
-
然后,我们更新
buy2和sell2:buy2 = Math.max(buy2, sell1 - price[i]):更新第二次买入股票的最大利润。我们取第一次卖出股票后获得的利润与之前的buy2比较,选择较大的那个。sell2 = Math.max(sell2, buy2 + price[i]):更新第二次卖出股票的最大利润。我们将第二次买入股票后获得的利润与之前的sell2比较,选择较大的那个。
-
最后返回
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)。我们只使用了常数个额外变量。