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 k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.
用local[i][j]表示到达第i天时,最多进行j次交易的局部最优解;用global[i][j]表示到达第i天时,最多进行j次的全局最优解。它们二者的关系如下(其中diff = prices[i] – prices[i – 1]):
local[i][j] = max(global[i – 1][j – 1] , local[i – 1][j] + diff)
global[i][j] = max(global[i – 1][j], local[i][j])
local[i][j]和global[i][j]的区别是:local[i][j]意味着在第i天一定有交易(卖出)发生,当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即local[i][j]=local[i-1][j]+diff;当第i天的价格不高于第i-1天(即diff<=0)时,那么local[i][j]=global[i-1][j-1]+diff,而由于diff<=0,所以可写成local[i][j]=global[i-1][j-1]。global[i][j]就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:如果第i天没有交易(卖出),那么global[i][j]=global[i-1][j];如果第i天有交易(卖出),那么global[i][j]=local[i][j]。
//if(k >= days) go to II //k < days //local[0][0] = 0; global[0][0] //local[i][j] = Math.max(local[i-1][j] + differ, global[i-1][j-1]); 在第i天一定进行交易 diff >0 //global[i][j] = Math.max(local[i][j], global[i-1][j]); 在第i 天进行交易,或者不进行交易 public class Solution { public int maxProfit(int k, int[] prices) { if(prices == null || prices.length <= 1 || k==0) return 0; int days = prices.length; if(k >= days) return getMaxProfit(prices); // question II int local[][] = new int[days][k+1]; int global[][] = new int[days][k+1]; local[0][0] = 0; global[0][0] = 0; for(int i = 1; i < days ; i++){ int diff = prices[i] - prices[i-1]; for(int j = 1 ; j <= k ; j ++){ local[i][j] = Math.max(local[i-1][j] + diff, global[i-1][j-1]); global[i][j] = Math.max(local[i][j], global[i-1][j]); } } return global[days-1][k]; } public int getMaxProfit(int[] prices) { int total = 0; for(int i = 1; i < prices.length; i++){ if(prices[i] > prices[i-1]) total += prices[i]-prices[i-1]; } return total; } }