题目
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).
一种巧妙的解法,参考Best Time to Buy and Sell Stock的思路,可以从前往后算出当前节点最为最后一个节点所能得到的最大收益值;类似地,可以从后往前,得到当前节点作为第一个节点所能得到的最大收益值。那么至少两次交易所能得到的最大值就是以某个节点为分界线,前后两端最大收益的和(有可能有一段无收益,即只有一次交易)。具体实现见代码1。
还有种能在O(k*n)时间复杂度解决k次交易最大收益的牛逼解法,具体没有研读了,参考论文《Maximum-Scoring Segment Sets》。同时有人给出了C++的实现,能够顺利AC,参见代码2.
代码1
public class BestTimeToBuyAndSellStockIII { public int maxProfit(int[] prices) { if (prices == null || prices.length <= 1) { return 0; } int profit = 0; int N = prices.length; // forward traverse int[] forwardProfit = new int[N]; int valley = prices[0]; for (int i = 1; i < N; ++i) { valley = Math.min(valley, prices[i]); forwardProfit[i] = Math.max(forwardProfit[i - 1], prices[i] - valley); } // backward traverse int[] backwardProfit = new int[N]; int peak = prices[N - 1]; for (int i = N - 2; i >= 0; --i) { peak = Math.max(peak, prices[i]); backwardProfit[i] = Math.max(backwardProfit[i + 1], peak - prices[i]); profit = Math.max(profit, forwardProfit[i] + backwardProfit[i]); } return profit; } }代码2
int maxProfit(vector<int> &prices) { vector<bool> segs(prices.size()); int maxprofit = 0; for (int transact = 0; transact < 2; ++transact) { int i0 = 0, c = 0, cmax = 0; vector<int> s; for (int i = 0; i < (int)prices.size()-1; ++i) { if (i > 0 && segs[i] != segs[i-1]) { i0 = i; c = 0; } c = c + prices[i+1] - prices[i]; if ((!segs[i] && c <= 0) || (segs[i] && c >= 0)) { i0 = i+1; c = 0; } else if (cmax < abs(c)) { cmax = abs(c); s = {i0, i}; } } if (cmax == 0) break; for (int i = s[0]; i <= s[1]; ++i) segs[i] = !segs[i]; maxprofit += cmax; } return maxprofit; }
LeetCode | Best Time to Buy and Sell Stock III
原文:http://blog.csdn.net/perfect8886/article/details/19765219