买卖股票的最佳时机 III - 困难

*************

C++

topic: 123. 买卖股票的最佳时机 III - 力扣(LeetCode)

*************

Check the topic:

Yeaterday I bought a stock too:

买卖股票的最佳时期II - 中等难度-优快云博客icon-default.png?t=O83Ahttps://blog.youkuaiyun.com/ElseWhereR/article/details/144494377?spm=1001.2014.3001.5501

In yesterday project, times to deal is free while todays deal-time-limitation is two. It seems nothing familar.

What if the deal time is only once? Then it comes easy, just find the minimum price and find the max profit:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int minPrice = prices[0]; // 迄今为止遇到的最低价格
        int maxPro = 0; // 最大利润
        
        for (int i = 1; i < prices.size(); ++i) {
            // 如果当前价格比迄今为止的最低价格还低,更新最低价格
            if (prices[i] < minPrice) {
                minPrice = prices[i];
            } else {
                // 如果当前价格比最低价格高,计算利润,并更新最大利润
                maxPro = max(maxPro, prices[i] - minPrice);
            }
        }
        
        return maxPro;
    }
};

If the deal-time is not limited, like yesterday topic:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int maxPro = 0; // 最大利润
        
        for (int i = 1; i < prices.size(); ++i) {
            // 如果今天的价格比昨天高,那么我们就可以认为昨天买入今天卖出
            if (prices[i] > prices[i - 1]) {
                maxPro += prices[i] - prices[i - 1];
            }
        }
        
        return maxPro;
    }
};

and now, the deal-time is two. And the first sale is the same, find the min price to buy and the max price to sale:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size();

        // 第一次买入和卖出的最大利润
        int firstBuy = -prices[0], firstSell = 0;       

        for (int i = 1; i < n; ++i) {
            // 更新第一次买入的最大利润
            firstBuy = max(firstBuy, -prices[i]);
            // 更新第一次卖出的最大利润
            firstSell = max(firstSell, firstBuy + prices[i]);
           
    }
};

here do a little change:

  // 如果当前价格比迄今为止的最低价格还低,更新最低价格
            if (prices[i] < minPrice) {
                minPrice = prices[i];

the code here can be more concise like this:

// 如果当前价格比迄今为止的最低价格还低,更新最低价格
          
if (prices[i] < minPrice) {
    minPrice = prices[i];


//
int firstBuy = -price[0]             
firstBuy = max(firstBuy, -prices[i]);

Just some mathematic tricks.

 For the second deal, the second min buy price is:

 secondBuy = max(secondBuy, firstSell - prices[i]);

For your attention, sale and buy are allowed to happen at the same day.

So the second sale is :

  secondSell = max(secondSell, secondBuy + prices[i]);

The code is easy to write:

get the length always comes first:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size(); // get the length
    }
};

Then comes initializing:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size(); // get the length

        int firstBuy = - prices[0];
        int firstSale = 0;
        int secondBuy = - prices[0];
        int secondSale = 0;

        // do sth. here
    }
};

Find the minimum price in the i day:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size(); // get the length

        int firstBuy =  prices[0];
        int firstSale = 0;
        int secondBuy = prices[0];
        int secondSale = 0;

        // do sth. here
        for (int i = 1; i < n; i++){
            firstBuy = min(firstBuy, prices[i]);
            firstSale = max(firstSale, first - prices[i]);

        }
    }
};

After the first sale comes the second sale:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size(); // get the length

        int firstBuy =  prices[0];
        int firstSale = 0;
        int secondBuy = prices[0];
        int secondSale = 0;

        // do sth. here
        for (int i = 1; i < n; i++){
            firstBuy = min(firstBuy, prices[i]);
            firstSale = max(firstSale, firstSale - prices[i]);

            // the second sale
            secondBuy = min(secondBuy, firstSale - prices[i]);
            secondSale = max(secondSale, prices[i] - secondSale);
        }

        return secondSale;
    }
};

but the code doesnot run:

Inspect the code then find the logic is something wrong: every step means the maxprofit, not the price. All the firstBuy and firstSale should be the benefits:

  • if buy, the profit should be - price[i]
  • if sale, the profit should be sale - price[i]

and makes the code more elegant:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n = prices.size(); // get the length

        int firstBuy = - prices[0];
        int firstSale = 0;
        int secondBuy = - prices[0];
        int secondSale = 0;

        // do sth. here
        for (int i = 1; i < n; i++){
            firstBuy = max(firstBuy, - prices[i]);
            firstSale = max(firstSale, prices[i] + firstBuy);

            // the second sale
            secondBuy = max(secondBuy, firstSale - prices[i]);
            secondSale = max(secondSale, prices[i] + secondBuy);
        }

        return secondSale;
    }
};

It works.

And if the dael time is 3 times:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty()) return 0;

        int n = prices.size();
        // 初始化状态变量
        int firstBuy = -prices[0];  // 第一次买入的最大利润
        int firstSell = 0;          // 第一次卖出的最大利润
        int secondBuy = -prices[0]; // 第二次买入的最大利润
        int secondSell = 0;         // 第二次卖出的最大利润
        int thirdBuy = -prices[0];  // 第三次买入的最大利润
        int thirdSell = 0;          // 第三次卖出的最大利润

        for (int i = 1; i < n; ++i) {
            // 更新第一次买入的最大利润
            firstBuy = max(firstBuy, -prices[i]);
            // 更新第一次卖出的最大利润
            firstSell = max(firstSell, firstBuy + prices[i]);
            // 更新第二次买入的最大利润
            secondBuy = max(secondBuy, firstSell - prices[i]);
            // 更新第二次卖出的最大利润
            secondSell = max(secondSell, secondBuy + prices[i]);
            // 更新第三次买入的最大利润
            thirdBuy = max(thirdBuy, secondSell - prices[i]);
            // 更新第三次卖出的最大利润
            thirdSell = max(thirdSell, thirdBuy + prices[i]);
        }

        return thirdSell;
    }
};

Some where in the world that aren't made out of stone, there's something inside them that they can't get to, that they can't touch. That's yours. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值