题目
题目描述
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:prices = [3,3,5,0,0,3,1,4]
输出:6
解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这个情况下, 没有交易完成, 所以最大利润为 0。
示例 4:
输入:prices = [1]
输出:0
提示:
1 <= prices.length <=
1
0
5
10^5
105
0 <= prices[i] <=
1
0
5
10^5
105
题解
这个问题可以通过动态规划(Dynamic Programming, DP)来解决,允许最多进行两次交易。我们需要维护四个状态变量来跟踪在不同情况下的最大利润:
- 第一次买入后的最大利润 (
first_buy) - 第一次卖出后的最大利润 (
first_sell) - 第二次买入后的最大利润 (
second_buy) - 第二次卖出后的最大利润 (
second_sell)
动态规划解决方案
-
初始化:
first_buy初始化为负无穷大,表示还没有进行任何买入操作。first_sell初始化为 0,因为在没有买入之前,没有利润。second_buy同样初始化为负无穷大,因为还没有进行第二次买入。second_sell初始化为 0。
-
遍历每一天的价格,并更新上述四个状态变量:
- 更新
first_buy为当前价格减去之前的利润或者保持原来的值中的较大者(即如果今天买入会更好)。 - 更新
first_sell为当前价格加上之前的买入成本或者保持原来的值中的较大者(即如果今天卖出会更好)。 - 更新
second_buy为first_sell减去当前价格或者保持原来的值中的较大者(即如果在今天进行第二次买入会更好)。 - 更新
second_sell为当前价格加上之前的第二次买入成本或者保持原来的值中的较大者(即如果今天进行第二次卖出会更好)。
- 更新
最终,second_sell 将包含我们可以获得的最大利润。
Python 实现
下面是具体的实现代码:
def maxProfit(prices):
if not prices:
return 0
first_buy, first_sell = float('-inf'), 0
second_buy, second_sell = float('-inf'), 0
for price in prices:
# 更新第一次买入和卖出的状态
first_buy = max(first_buy, -price)
first_sell = max(first_sell, first_buy + price)
# 更新第二次买入和卖出的状态
second_buy = max(second_buy, first_sell - price)
second_sell = max(second_sell, second_buy + price)
return second_sell
解释
first_buy和first_sell:用于追踪第一次买入和卖出后的最大利润。second_buy和second_sell:用于追踪第二次买入和卖出后的最大利润。- 遍历逻辑:通过遍历价格列表,逐步更新这些状态变量,确保我们能够捕捉到所有可能的买入和卖出机会,从而计算出最大利润。
这种方法的时间复杂度为 O(n),因为我们只需要遍历一次价格列表;空间复杂度为 O(1),因为我们只使用了有限的额外变量。这种解决方案既高效又简洁,非常适合处理大规模数据。
提交结果


1780

被折叠的 条评论
为什么被折叠?



