lc188.java 1.5 KB
Newer Older
L
liu13 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
package code;
/*
 * 188. Best Time to Buy and Sell Stock IV
 * 题意:买卖股票最大利润,可以买卖k次
 * 难度:Hard
 * 分类:Dynamic Programming
 * 思路:二维dp, dp[i][j] 表示i次交易,在数组prices[0~j]上的最大利润
 *      dp[i][j] = Max( dp[i][j-1], dp[i-1][jj]+prices[j]-prices[jj] )   { jj in range of [0, j-1] }
 *               = Max( dp[i][j-1], prices[j]+ max(dp[i-1][jj]-prices[jj]) ) 转化为这一步,少了一层循环
 *      dp[0][j] = 0;  dp[i][0] = 0;
 * Tips:lc121, lc309, lc188, lc123, lc714
 */
public class lc188 {
    public int maxProfit(int k, int[] prices) {
        if(prices.length==0) return 0;
        int n = prices.length;
        //if k >= n/2, then you can make maximum number of transactions.
        if (k >=  n/2) {
            int maxPro = 0;
            for (int i = 1; i < n; i++) {
                if (prices[i] > prices[i-1])
                    maxPro += prices[i] - prices[i-1];
            }
            return maxPro;
        }

        int[][] dp = new int[k+1][prices.length];
        for (int i = 1; i <= k ; i++) {
            int localMax = -prices[0];
            for (int j = 1; j < prices.length ; j++) {  //jj的计算和这一维合并,总的复杂度是二次方而不是三次
                dp[i][j] = Math.max(dp[i][j-1], prices[j]+localMax);
                localMax = Math.max(localMax, dp[i-1][j]-prices[j]);
            }
        }
        return dp[k][prices.length-1];
    }
}