Day52~123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

69 阅读3分钟

摘要

本文主要介绍了LeetCode动态规划的几个题目,包括123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV。

1、123.买卖股票的最佳时机III

1.1 代码

  • 动规五部曲

    • dp 数组以及下标的含义

      • dp[0][i] 代表不持有股票的最大利润
      • dp[1][i] 代表第一次持有股票的最大金额
      • dp[2][i] 代表第一次卖出股票的最大金额
      • dp[3][i] 代表第二次持有股票的最大金额
      • dp[4][i] 代表第二次卖出股票的最大金额
    • 递推公式

      • dp[0][i] = dp[0][i-1]
      • dp[1][i] = Math.max(dp[1][i-1], dp[0][i-1] - prices[i])
      • dp[2][i] = Math.max(dp[2][i-1], dp[1][i-1] + prices[i])
      • dp[3][i] = Math.max(dp[3][i-1], dp[2][i-1] - prices[i])
      • dp[4][i] = Math.max(dp[4][i-1], dp[3][i-1] + prices[i])
    • dp 数组如何初始化

      • dp[0][0] = 0
      • dp[1][0] = -prices[0]
      • dp[2][0] = 0
      • dp[3][0] = -prices[0]
      • dp[4][0] = 0
    • dp 数组遍历顺序

      • 从前向后遍历
    • 打印 dp 数组

      • 以输入[1,2,3,4,5]为例
      • 123.买卖股票的最佳时机III

1.2 思路

    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[5][len];
        dp[0][0] = 0;
        dp[1][0] = -prices[0];
        dp[2][0] = 0;
        dp[3][0] = -prices[0];
        dp[4][0] = 0;
​
        for(int i=1; i<len; i++) {
            dp[0][i] = dp[0][i-1];
            dp[1][i] = Math.max(dp[1][i-1], dp[0][i-1] - prices[i]);
            dp[2][i] = Math.max(dp[2][i-1], dp[1][i-1] + prices[i]);
            dp[3][i] = Math.max(dp[3][i-1], dp[2][i-1] - prices[i]);
            dp[4][i] = Math.max(dp[4][i-1], dp[3][i-1] + prices[i]);
        }
        return dp[4][len-1];
    }

2、188.买卖股票的最佳时机IV *

2.1 代码

  • 动规五部曲

    • dp 数组以及下标的含义

      • i 的状态表示, 除了0以外,偶数就是卖出,奇数就是买入

        • 0 表示不操作
        • 1 第一次买入
        • 2 第一次卖出
        • 3 第二次买入
        • 4 第二次卖出
    • 递推公式

      • dp[i+1][j] = Math.max(dp[i+1][j-1], dp[i][j-1] - prices[j])

        • 第 j 天没有操作
        • 第 j 天买入股票了
      • dp[i+2][j] = Math.max(dp[i+2][j-1], dp[i+1][j-1] + prices[j])

        • 第 j 天没有操作
        • 第 j 天卖出股票了
    • dp 数组如何初始化

      • dp[0][0] =0
      • dp[i+1][0] = -prices[0]
      • dp[i+2][0] = 0
    • dp 数组遍历顺序

      • 从前向后遍历
    • 打印 dp 数组

      • 以输入[1,2,3,4,5],k=2为例
      • 188.买卖股票的最佳时机IV
  • 注意事项

    • i 的状态表示, 除了0以外,偶数就是卖出,奇数就是买入

      • 0 表示不操作

        • dp[0][0] =0
      • 1 第一次买入

      • 2 第一次卖出

      • 3 第二次买入

      • 4 第二次卖出

2.2 思路

    public int maxProfit(int k, int[] prices) {
        int len = prices.length;
        if(k==0 || len==0) {
            return 0;
        }
​
        int[][] dp = new int[2*k+1][len];
        dp[0][0] =0;
        for(int i=0; i<2*k; i+=2) {
            dp[i+1][0] = -prices[0];
            dp[i+2][0] = 0;
        }
​
        for(int j=1; j<len; j++) {
            for(int i=0; i<2*k; i+=2) {
                dp[i+1][j] = Math.max(dp[i+1][j-1], dp[i][j-1] - prices[j]);
                dp[i+2][j] = Math.max(dp[i+2][j-1], dp[i+1][j-1] + prices[j]);
            }
        }
        return dp[2*k][len-1];
    }

参考资料

代码随想录-123.买卖股票的最佳时机III

代码随想录-188.买卖股票的最佳时机IV