动态规划(08)

64 阅读1分钟

Day13 股票问题(03)

1、309. 最佳买卖股票时机含冷冻期

  • 思路:
    • 买卖有冷冻期,对应一般的股票问题相当于buy[i] = sell[i-2] - price[i]

      注意第1天持有股票的的base case仍为 Max[dp[0][1],dp[0][0]price[1]]Max[dp[0][1],dp[0][0]-price[1]]

    • coding
      class Solution {
          public int maxProfit(int[] prices) {
              int len = prices.length;
              int[][] dp = new int[len][2];
              for (int i = 0; i < len; i++) {
                  if (i == 0) {
                      dp[i][0] = 0;
                      dp[i][1] = -prices[0];
                      continue;
                  }
                  if (i == 1) {
                      dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
                      //第一天持有股票的最大利润 为dp[0][1]  dp[0][0]-prices[i] !!!
                      dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
                      continue;
                  }
                  dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
                  dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
      
              }
              return dp[len - 1][0];
          }
      }
      
    • 复杂度优化
      class Solution {
          public int maxProfit(int[] prices) {
              int len = prices.length;
              int[] buy = new int[len];
              int[] sell = new int[len];
              for (int i = 0; i < len; i++) {
                  if (i == 0) {
                      buy[0] = -prices[i];
                      sell[0] = 0;
                      continue;
                  }
                  if (i == 1) {
                      //第一天持有股票的最大利润 为dp[0][1]  dp[0][0]-prices[i] !!!
                      buy[i] = Math.max(buy[i - 1], sell[i - 1] - prices[i]);
                      sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
                      continue;
                  }
                  buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
                  sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
              }
              return sell[len - 1];
          }
      }
      class Solution {
          public int maxProfit(int[] prices) {
              int len = prices.length;
              int buy = -prices[0];
              int sell = 0;
              int sellT = 0;
              for (int i = 1; i < len; i++) {
                  if (i == 1) {
                      //第一天持有股票的最大利润 为dp[0][1]  dp[0][0]-prices[i] !!!
                      buy = Math.max(buy, sell - prices[i]);
                      sell = Math.max(sell, buy + prices[i]);
                      continue;
                  }
                  buy = Math.max(buy, sellT - prices[i]);
                  sellT = sell;
                  sell = Math.max(sell, buy + prices[i]);
      
              }
              return sell;
          }
      }
      

2、714. 买卖股票的最佳时机含手续费

  • 思路:
    • 买卖股票有冷冻期,即买的时候价格更高需要扣除手续费
  • 题解
     class Solution {
        public int maxProfit(int[] prices, int fee) {
            int n = prices.length;
            int buy = -(prices[0] + fee);
            int sell = 0;
            for (int i = 1; i < n; i++) {
                buy = Math.max(buy, sell - prices[i] - fee);
                sell = Math.max(sell, buy + prices[i]);
            }
            return sell;
        }
    }
    

小结

  1. 股票问题主要需要掌握股票的状态转移,即
  • buy[i]=MAX[buy[i1],sell[i1]price[i]]buy[i] = MAX[buy[i-1],sell[i - 1] - price[i]]
  • sell[i]=MAX[sell[i1],buy[i1]+price[i]]sell[i]= MAX[sell[i-1],buy[i - 1] + price[i]]
  1. 注意base case