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).
Analyse: Consider a dp function s.t. dp[i] = max_profit[0,....i-1] + max_profit[i,...n]. Then the problem is transferred to compute the max dp[i]. To get max profit of a interval, we can use the code in here. You have to pay special attention that the LEFT AND RIGHT PART of a indexed number are COMPLETED SEPERATED.
1. Time Exceeded.
This is because when calling the dp function, we repeat the computation for a lot of times.
1 class Solution { 2 public: 3 int maxProfit(vector<int>& prices) { 4 if(prices.size() <= 1) return 0; 5 6 int result = 0; 7 for(int i = 0; i < prices.size(); i++){ 8 result = max(result, dp(prices, 0, i) + dp(prices, i, prices.size())); 9 } 10 return result; 11 } 12 int dp(vector<int>& prices, int start, int end) { 13 if(start == end) return 0; 14 15 int result = 0, pre = 0; 16 int lowest = prices[start]; 17 for(int i = start + 1; i < end; i++){ 18 result = max(pre, prices[i] - lowest); 19 lowest = min(lowest, prices[i]); 20 pre = result; 21 } 22 return result; 23 } 24 };
2. To solve the above problem, we can store the computed information in an array, for example, a[] store the computed information in the left part and b[] store the computed information in the right part.
Runtime: 12ms.
1 class Solution { 2 public: 3 int maxProfit(vector<int>& prices) { 4 if(prices.size() <= 1) return 0; 5 6 const int n = prices.size(); 7 int left[n] = {0}, right[n] = {0}; 8 dp(prices, left, right); 9 int result = 0; 10 for(int i = 0; i < prices.size(); i++){ 11 result = max(result, left[i] + right[i]); 12 } 13 return result; 14 } 15 void dp(vector<int>& prices, int left[], int right[]) { 16 int lowest = prices[0]; 17 for(int i = 1; i < prices.size(); i++){//to initial the left part of the indexed number 18 left[i] = max(left[i - 1], prices[i] - lowest); 19 lowest = min(lowest, prices[i]); 20 } 21 22 int highest = prices[prices.size() - 1]; 23 right[prices.size() - 1] = 0; 24 for(int j = prices.size() - 2; j >= 0; j--){ 25 right[j] = max(right[j + 1], highest - prices[j]); 26 highest = max(highest, prices[j]); 27 } 28 } 29 };