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:
A transaction is a buy & a sell. You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Analysis
Comparing to I and II, III limits the number of transactions to 2. This can be solve by “devide and conquer”. We use left[i] to track the maximum profit for transactions before i, and use right[i] to track the maximum profit for transactions after i. You can use the following example to understand the Java solution:
Prices: 1 4 5 7 6 3 2 9 left = [0, 3, 4, 6, 6, 6, 6, 8] right= [8, 7, 7, 7, 7, 7, 7, 0]
The maximum profit = 13
Java Solution
public int maxProfit(int[] prices) { if (prices == null || prices.length < 2) { return 0; } //highest profit in 0 ... i int[] left = new int[prices.length]; int[] right = new int[prices.length]; // DP from left to right left[0] = 0; int min = prices[0]; for (int i = 1; i < prices.length; i++) { min = Math.min(min, prices[i]); left[i] = Math.max(left[i - 1], prices[i] - min); } // DP from right to left right[prices.length - 1] = 0; int max = prices[prices.length - 1]; for (int i = prices.length - 2; i >= 0; i--) { max = Math.max(max, prices[i]); right[i] = Math.max(right[i + 1], max - prices[i]); } int profit = 0; for (int i = 0; i < prices.length; i++) { profit = Math.max(profit, left[i] + right[i]); } return profit; } |
left/right arrays could be combined into one.
Wouldn’t it be more useful if the method returned a list of days instead of the maximum profit?
For those in the comments from the past, or for those that see this in the future, when he got the arrays in the top where it says:
Prices: 1 4 5 7 6 3 2 9
left = [0, 3, 4, 6, 6, 6, 6, 8]
right= [8, 7, 7, 7, 7, 7, 7, 0]
He did this by subtracting the values from left-to-right and right-to-left. For the “left” array: prices[i] – prices[i-1], where i began at 1 and then appending that result to the “left” array. For the “right” array: prices[len(prices) – 1] – prices[len(prices) – 2] ..etc and inserting at the beginning of the array, where the integers would be the iterator variable in the for loop.
I hope that cleared that up for several of you!
I did the same approach, but you will see that it does not work for some test cases
This problem can be solved at O(N) by DP too.
We can track first two max PROFIT values.
Prices: 1 4 5 7 6 3 2 9
we buy 1 and sell it when price decreases at 7. And buy 2, cell for 9 and so on.
So, we take maximum two profit points and add them.
Hello. How did you get these arrays, left = [0, 3, 4, 6, 6, 6, 6, 8], right= [8, 7, 7, 7, 7, 7, 7, 0] and how did you calculate The maximum profit = 13 from these arrays. It is too obscure for me and messed up my mind. Thanks for your help.
min = Math.min(min, prices[i]);
this has to e after finding left[i].
Could you please explain how you get this array?
right= [8, 7, 7, 7, 7, 7, 7, 0]
How can we return the indexes as well?