LeetCode - 解题笔记 - 123 - Best Time to Buy and Sell Stock III

Solution 1

0121. Best Time to Buy and Sell Stock 的进一步扩展,在不限制同期买卖的情况下,仅能进行最多两次买卖的最大收益方案,显然是一个动态规划了。但是我还没学会这种多状态的动态规划

【参考官方】整个过程涉及到五个状态:什么都不做、第一次买入和卖出、第二次买入和卖出。由于第一个状态的收益会自动合并到其余的四个状态上(直接等于前一个状态),因此状态转移(即收益变化)为:

{  buy  1 = max ⁡ {  buy  1 , −  prices  [ i ] }  sell  1 = max ⁡ {  sell  1 ,  buy  1 +  prices  [ i ] }  buy  2 = max ⁡ {  buy  2 ,  sell  1 −  prices  [ i ] }  sell  2 = max ⁡ {  sell  2 ,  buy  2 +  prices  [ i ] } \left\{\begin{array}{l}\text { buy }_{1}=\max \left\{\text { buy }_{1},-\text { prices }[i]\right\} \\\text { sell }_{1}=\max \left\{\text { sell }_{1}, \text { buy }_{1}+\text { prices }[i]\right\} \\\text { buy }_{2}=\max \left\{\text { buy }_{2}, \text { sell }_{1}-\text { prices }[i]\right\} \\\text { sell }_{2}=\max \left\{\text { sell }_{2}, \text { buy }_{2}+\text { prices }[i]\right\}\end{array}\right.  buy 1=max{ buy 1, prices [i]} sell 1=max{ sell 1, buy 1+ prices [i]} buy 2=max{ buy 2, sell 1 prices [i]} sell 2=max{ sell 2, buy 2+ prices [i]}

同时,由于允许同期买卖,因此可以从上到下逐个更新,因为上一个项目的更新不影响下一个结果(相当于当前完成了一次买卖,额外收益为0,不影响结果)。

初始状态,两个买入状态初始化为即为第一天的负报价(状态为收益,买入即负收益,对于第二次买入,如上所属相当于这一天买了卖了又卖了,额外收益为0),两个卖出状态为0(因为没有本金)

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入长度,线性遍历
  • 空间复杂度: O ( 1 ) O(1) O(1),仅维护常数个状态变量
class Solution {
public:
    int maxProfit(vector<int>& prices) {

        int buy1 = -prices[0], sell1 = 0;
        
        int buy2 = -prices[0], sell2 = 0;
        
        for (int i = 1; i < prices.size(); ++i) {
            buy1 = max(buy1, -prices[i]);
            sell1 = max(sell1, buy1 + prices[i]);
            
            buy2 = max(buy2, sell1 - prices[i]);
            sell2 = max(sell2, buy2 + prices[i]);
        }
        
        return sell2;

    }
};

Solution 2

Solution 1的Python实现

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        buy1, sell1 = -prices[0], 0
        buy2, sell2 = -prices[0], 0
        
        for i in range(1, len(prices)):
            buy1 = max(buy1, -prices[i])
            sell1 = max(sell1, buy1 + prices[i])
            
            buy2 = max(buy2, sell1 - prices[i])
            sell2 = max(sell2, buy2 + prices[i])
            
        return sell2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值