原题链接:
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/submissions/540747717/
完成情况:
解题思路:
上述代码实现了一个算法来计算在股票价格数组 prices
中最多进行两笔交易所能获得的最大利润。以下是对代码的详细解释:
public int maxProfit(int[] prices) {
// 设计一个算法来计算你所能获取的最大利润。你最多可以完成【两笔】交易。
// 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
int n = prices.length;
int buyFirst = -prices[0], sellFirst = 0;
int buySecond = -prices[0], sellSecond = 0;
for (int i = 1; i < n; i++) {
// 每一次都去寻找第一轮可以获得的最大利润
buyFirst = Math.max(buyFirst, -prices[i]);
sellFirst = Math.max(sellFirst, buyFirst + prices[i]);
// 每一次寻找都在 sellFirst 的利润上,去寻找第二次能获取到的最大利润
buySecond = Math.max(buySecond, sellFirst - prices[i]);
sellSecond = Math.max(sellSecond, buySecond + prices[i]);
}
return sellSecond;
}
变量解释
buyFirst
:表示进行第一笔交易时,买入股票后所能得到的最大净利润(负数表示支出)。sellFirst
:表示进行第一笔交易时,卖出股票后所能得到的最大净利润。buySecond
:表示在进行第二笔交易时,买入股票后所能得到的最大净利润(基于第一笔交易的利润)。sellSecond
:表示进行第二笔交易时,卖出股票后所能得到的最大净利润。
算法流程
-
初始化:
buyFirst
和buySecond
初始为-prices[0]
,表示在第一天买入股票时的成本。sellFirst
和sellSecond
初始为 0,表示在还没有卖出股票时的利润为零。
-
遍历价格数组:
- 从第二天开始遍历价格数组
prices
,在每一天计算可能的最大利润。
- 从第二天开始遍历价格数组
-
更新第一笔交易的买入和卖出状态:
buyFirst = Math.max(buyFirst, -prices[i]);
:更新第一次买入股票时的最优状态,取当前已知的最优值和在第i
天买入股票的最大值。sellFirst = Math.max(sellFirst, buyFirst + prices[i]);
:更新第一次卖出股票时的最优状态,取当前已知的最优值和在第i
天卖出股票的最大值(包括买入后的利润)。
-
更新第二笔交易的买入和卖出状态:
buySecond = Math.max(buySecond, sellFirst - prices[i]);
:更新第二次买入股票时的最优状态,取当前已知的最优值和在第i
天买入股票的最大值(包括第一次卖出的利润)。sellSecond = Math.max(sellSecond, buySecond + prices[i]);
:更新第二次卖出股票时的最优状态,取当前已知的最优值和在第i
天卖出股票的最大值(包括第二次买入后的利润)。
最终结果
循环结束后,sellSecond
保存了最多进行两笔交易所能获得的最大利润。
例子
假设 prices = [3,3,5,0,0,3,1,4]
:
- 第一笔交易的最大利润是
5 - 3 = 2
。 - 第二笔交易的最大利润是
4 - 0 = 4
。
总利润为 2 + 4 = 6
,该算法会正确计算出结果。
参考代码:
_123买卖股票的最佳时机III
package leetcode板块;
public class _123买卖股票的最佳时机III {
/**
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
//设计一个算法来计算你所能获取的最大利润。你最多可以完成 【两笔】 交易。
//注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
// TODO 每一轮都去记录当前的第一次买卖的最大值
// 第二轮则去和每一次记录的第一轮进行比较
int n = prices.length;
int buyFirst = -prices[0],sellFirst = 0;
int buySecond = -prices[0],sellSecond = 0;
for (int i = 1;i<n;i++){
// TODO 每一次都去寻找第一轮可以获得的最大利润
buyFirst = Math.max(buyFirst,-prices[i]);
sellFirst = Math.max(sellFirst,buyFirst + prices[i]);
// TODO 每一次寻找都在 sellFirst 的利润上,去寻找第二次能获取到的最大利润
buySecond = Math.max(buySecond,sellFirst - prices[i]);
sellSecond = Math.max(sellSecond,buySecond + prices[i]);
}
return sellSecond;
}
}