代码随想录算法训练营 day 50: ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

63 阅读1分钟

123. Best Time to Buy and Sell Stock III

DP数组为二维。 第一维是每日,第二维是每日的操作。数组存放本日做过本操作的最大钱数。 操作有5种:

  1. 不做操作
  2. 买进第一手
  3. 卖出第一手
  4. 买进第二手
  5. 卖出第二手

要注意每项操作是要依赖于前一项的。

class Solution {
    public int maxProfit(int[] prices) {
        int[][] dp = new int[prices.length][5];

        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        dp[0][2] = 0;
        dp[0][3] = -prices[0];
        dp[0][4] = 0;

        for(int i=1; i<prices.length; i++) {
            dp[i][0] = dp[i-1][0];
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
            dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1] + prices[i]);
            dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2] - prices[i]);
            dp[i][4] = Math.max(dp[i-1][4], dp[i-1][3] + prices[i]);
        }

        return dp[prices.length-1][4];

    }
}

188. Best Time to Buy and Sell Stock IV

前一题的进阶版。但难度没升多少。总计有2K+1项操作,注意奇数偶数操作的规律。

class Solution {
    public int maxProfit(int k, int[] prices) {
        int[][] dp = new int[prices.length][2 * k + 1];

        int row = prices.length;
        int col = 2*k + 1;

        for(int i=0; i<col; i++) {
            if(i % 2 == 0) {
                dp[0][i] = 0;
            }
            else {
                dp[0][i] = -prices[0];  
            }
        }


        for(int i=1; i<row; i++) {
            dp[i][0] = dp[i-1][0];
            for(int j=1; j<col; j++) {
                int alt = 0;
                if(j%2 == 1) {
                    alt = -prices[i];
                }
                else {
                    alt = prices[i];
                }
                dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-1] + alt); 
            }
        }

        return dp[row-1][col-1];
    }
}