[Coding Made Simple] Buy/Sell stock with at most K transactions to maximize profit
Given an array of length n that stores a stock's price in n consecutive days, Buy/Sell stock with at most K transactions to maximize profit.
You must finish one transcation before you start the next transcation.
For some given prices of consecutive days prices[0 ~ i], on day i, we can either finish the last transcation by selling at prices[i],
or we do not have any transcations happening on day i.
f(i, k) = max of {f(i - 1, k), max of {prices[i] - prices[j] + f(j, k - 1), j is from day 0 to day i - 1} }
since one transcation muse be finished before the next one starts, it means if we finish the kth transcation on day i, all the previous k - 1 transcations must happen before day i, excluding day i.
Solution 1. Recursion
1 public class StockTranscation { 2 public int getMaxProfitRecursion(int[] prices, int k) { 3 if(prices == null || prices.length <= 1 || k <= 0) { 4 return 0; 5 } 6 return recursionHelper(prices, prices.length - 1, k); 7 } 8 private int recursionHelper(int[] prices, int day, int k) { 9 if(day <= 0 || k == 0) { 10 return 0; 11 } 12 int max = recursionHelper(prices, day - 1, k); 13 for(int i = 0; i < day; i++) { 14 max = Math.max(max, prices[day] - prices[i] + recursionHelper(prices, i, k - 1)); 15 } 16 return max; 17 } 18 public static void main(String[] args) { 19 int[] prices = {2,5,7,1,4,3,1,3}; 20 StockTranscation test = new StockTranscation(); 21 System.out.println(test.getMaxProfitDp(prices, 3)); 22 } 23 }
Solution 2. Dynamic Programming, O(n * n * k) runtime, O(n*k) space
1 public int getMaxProfitDp(int[] prices, int k) { 2 if(prices == null || prices.length <= 1 || k <= 0) { 3 return 0; 4 } 5 int[][] profit = new int[k + 1][prices.length]; 6 //profit is 0 when there is 0 transcation 7 for(int j = 0; j < prices.length; j++) { 8 profit[0][j] = 0; 9 } 10 //profit is 0 when there is the first day's stock price info 11 for(int i = 0; i <= k; i++) { 12 profit[i][0] = 0; 13 } 14 for(int i = 1; i <= k; i++) { 15 for(int j = 1; j < prices.length; j++) { 16 profit[i][j] = profit[i][j - 1]; 17 for(int t = 0; t < j; t++) { 18 profit[i][j] = Math.max(profit[i][j], prices[j] - prices[t] + profit[k - 1][t]); 19 } 20 } 21 } 22 return profit[k][prices.length - 1]; 23 }
Solution 3. Dynamic Programming, O(n * k) runtime, O(n * k) space