123.买卖股票的最佳时间Ⅲ python

题目

题目描述

给定一个数组,它的第 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)来解决,允许最多进行两次交易。我们需要维护四个状态变量来跟踪在不同情况下的最大利润:

  1. 第一次买入后的最大利润 (first_buy)
  2. 第一次卖出后的最大利润 (first_sell)
  3. 第二次买入后的最大利润 (second_buy)
  4. 第二次卖出后的最大利润 (second_sell)

动态规划解决方案

  • 初始化:

    • first_buy 初始化为负无穷大,表示还没有进行任何买入操作。
    • first_sell 初始化为 0,因为在没有买入之前,没有利润。
    • second_buy 同样初始化为负无穷大,因为还没有进行第二次买入。
    • second_sell 初始化为 0。
  • 遍历每一天的价格,并更新上述四个状态变量:

    • 更新 first_buy 为当前价格减去之前的利润或者保持原来的值中的较大者(即如果今天买入会更好)。
    • 更新 first_sell 为当前价格加上之前的买入成本或者保持原来的值中的较大者(即如果今天卖出会更好)。
    • 更新 second_buyfirst_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_buyfirst_sell:用于追踪第一次买入和卖出后的最大利润。
  • second_buysecond_sell:用于追踪第二次买入和卖出后的最大利润。
  • 遍历逻辑:通过遍历价格列表,逐步更新这些状态变量,确保我们能够捕捉到所有可能的买入和卖出机会,从而计算出最大利润。

这种方法的时间复杂度为 O(n),因为我们只需要遍历一次价格列表;空间复杂度为 O(1),因为我们只使用了有限的额外变量。这种解决方案既高效又简洁,非常适合处理大规模数据。

提交结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gxls2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值