Description:
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Link:
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
解题方法:
方法1:
因为只能做两次操作,所以肯定有一前一后,那么整个过程中的最大化收益值会出现在 在某一个时间点上前面最大收益加上后面最大收益中。
所以我们需要两个数组,第一个记录在某一时间点,前面最大收益;第二个记录在某一时间点,后面最大的收益。
最后遍历每个时间点将前面最大收益和后面最大收益相加。
方法2:
将整个操作过程当成4个人在操作,即一个做第一次买,一人做第一次卖,一人做第二次买,一人做第二次卖。买方的操作收益就是-price。第二次买卖需要依赖于第一次买卖的结果,这样可以保证两次买卖的一前一后顺序。
Tips:
Time Complexity:
方法1 O(n)时间 O(n)空间
方法2 O(n)时间 O(1)空间
完整代码:
//方法1:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(!len)
return 0;
vector<int> leftMax(len, 0);
vector<int> rightMax(len, 0);
int lMin = prices[0];
for(int i = 1; i < len; i++) {
if(lMin > prices[i])
lMin = prices[i];
//这一步代码很巧妙,每次都和前一次比较,这样最大收益会一直向后传递,大大降低代码复杂度
leftMax[i] = max(leftMax[i - 1], prices[i] - lMin);
cout<<leftMax[i]<<" ";
}
cout<<endl;
int rMax = prices[len - 1];
for(int i = len - 2; i >= 0; i--) {
if(rMax < prices[i])
rMax = prices[i];
rightMax[i] = max(rightMax[i + 1], rMax - prices[i]);
cout<<rightMax[i]<<" ";
}
cout<<endl;
int maxProfit = INT_MIN;
for(int i = 0; i < len; i++) {
maxProfit = max(leftMax[i] + rightMax[i], maxProfit);
}
return maxProfit;
}
//方法2:
int maxProfit(vector<int>& prices) {
int buy1 = INT_MIN, buy2 = INT_MIN, sell1 = 0, sell2 = 0;
for(int i: prices) {
buy1 = max(buy1, -i);
sell1 = max(sell1, buy1 + i);
buy2 = max(buy2, sell1 - i);
sell2 = max(sell2, buy2 + i);
}
return sell2;
}