123. Best Time to Buy and Sell Stock III
这道题是在121题上的进阶版本,但是我们依然可以通过求解121题的思路来求解这道题。首先我需要解释一下思路,因为代码的写法不适合去理解,我们知道第一次买股票的原则是和121题一样,我们记录最低的价格股票之后找到最高的差价,这个没有问题,那么关键点在于第二次购买股票,我们可以这样理解,如果现实中,你买卖了一次股票并且盈利了100元,那么现在股票价格是300元,我们认为是有价值购买的,所以我们会再次购买股票,此时盈利为-200 (算上我们之前的盈利),好了,那么我们需要做的是再次降低成本,也就是再次找到差价最高的,并且我们现在已经是在亏损200的情况下,所以在成本选择上我们需要减去这200元,具体看代码。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int OneBuy = INT_MAX;
int TwoBuy = INT_MAX;
int OneBuyOneSell = 0;
int TwoBuyTwoSell = 0;
for (int i = 0; i < prices.size(); i++)
{
int temp = prices[i];
OneBuy = min(temp, OneBuy);
OneBuyOneSell = max(temp - OneBuy, OneBuyOneSell);
TwoBuy = min(TwoBuy, temp - OneBuyOneSell);
TwoBuyTwoSell = max(TwoBuyTwoSell, temp - TwoBuy);
}
return TwoBuyTwoSell;
}
};
代码的书写其实不太利于阅读,我们可以逐行进行分析,首先我们定义了四个变量,第一次购买的价格,第一次售出后我们的盈利,第二次购买的价格(这里要注意,这里的价格不是真真的当天价格,而是需要减去第一次盈利的价格,或者说是亏损的成本),以及一个第二次的盈利。
我们来看for循环,OneBuy和OneBuyOneSell大家应该没有什么问题,主要的是TwoBuy的怎么求解,博主在这里也是想了很久,然后自己单步调试了两遍才算明白背后的直觉思想,为什么说是直觉,因为我感觉我解释不清为什么这样做是对的,但是他确实是这个道理,哈哈哈。好了,我们来具体走一遍。
i
3 3 5 0 0 3 1 4
int OneBuy = 3
int OneBuyOneSell = 0
int TwoBuy = 3
int TwoBuyTwoSell = 0;
i
3 3 5 0 0 3 1 4
int OneBuy = 3
int OneBuyOneSell = 0
int TwoBuy = 3
int TwoBuyTwoSell = 0;
i
3 3 5 0 0 3 1 4
int OneBuy = 3
int OneBuyOneSell = 5 - 3
int TwoBuy = 3
int TwoBuyTwoSell = 5 - 3
i
3 3 5 0 0 3 1 4
int OneBuy = 0
int OneBuyOneSell = 2
int TwoBuy = 0 - 2
int TwoBuyTwoSell = 0 - (-2)
i
3 3 5 0 0 3 1 4
int OneBuy = 0
int OneBuyOneSell = 2
int TwoBuy = 0 - 2
int TwoBuyTwoSell = 0 - (-2)
i
3 3 5 0 0 3 1 4
int OneBuy = 0
int OneBuyOneSell = 3
int TwoBuy = min(-2, (3 - 3) ) = -2
int TwoBuyTwoSell = 3 - (-2) = 5
(这里其实已经能看出来点TwoBuy记录的是我已经盈利了2,现在股票价格是3 我依然买,但是成本我需要再次下降)
i
3 3 5 0 0 3 1 4
int OneBuy = 0
int OneBuyOneSell = 3
int TwoBuy = min(-2, (1 - 3) ) = -2
int TwoBuyTwoSell = max(5, 1 - (-2) ) = 5
i
3 3 5 0 0 3 1 4
int OneBuy = 0
int OneBuyOneSell = 4
int TwoBuy = min(-2, 0) = -2
int TwoBuyTwoSell = max(5, (4 - (-2))) = 6
至此题目已经解答出,博主也是写了很多次勉强理解,我觉得还是要多思考,过段时间再来看一下,因为我觉得长时间不想一想应该忘得很快。好了不多说了。