【ATT】Best Time to Buy and Sell Stock III
Q: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).
A: 允许最多交易两次。
本质上是动态规划题目。
考虑Best Time to Buy and Sell Stock这道题,用O(n)的时间遍历数组就能找到maxProfit。本题也利用这个思想。
将数组分成两部分,分别求两部分的maxProfit,划分点可能在数组的任何位置。假设划分点是i。
forwardProfit[i]表示prices[0]~prices[i]之间交易一次的maxProfit;计算forwardProfit要从数组从头到尾扫描,记录valley。
forwardProfit[i] = max(forwardProfit[i-1],prices[i]-valley);
backProfit[i]表示prices[i]~prices[n-1]之间交易一次的maxProfit;计算backProfit要从数组末尾往前扫描,记录peek
backProfit[i] = max(backProfit[i+1],peek-prices[i]); //注意是backProfit[i+1]
那么总的maxProfit = max(forwardProfit[i]+backProfit[i]) i取0~n-1
注意:为什么不是forwardProfit[i-1]+backProfit[i]取最大值呢?!!!!!!!!要注意。
因为题目要求最多交易两次,因此能够交易一次,当前半部分sell的时间与后半部分buy的时间相等时,其实等价于只交易一次。
int maxProfit(vector<int> &prices) { // Start typing your C/C++ solution below // DO NOT write int main() function if(prices.empty()) return 0; vector<int> forwardProfit(prices.size()); vector<int> backProfit(prices.size()); int valley = prices[0]; forwardProfit[0] = 0; int i; int maxProfit = 0; for(i=1;i<prices.size();i++) { valley = min(valley,prices[i]); forwardProfit[i] = max(forwardProfit[i-1],prices[i]-valley); } int peek = prices[prices.size()-1]; backProfit[prices.size()-1] = 0; for(i=prices.size()-2;i>=0;i--) { peek = max(prices[i],peek); backProfit[i] = max(backProfit[i+1],peek-prices[i]); maxProfit = max(maxProfit,forwardProfit[i]+backProfit[i]); } return maxProfit; }