动态规划(6)

82 阅读1分钟

Day11 股票问题(1)

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

  • 思路:
    • 取dp数组,dp[i]表示第i天之前买卖股票的最大收益。
    • dp[i]=MAX[price[i]minPrice,dp[i1]]dp[i] = MAX[price[i] - minPrice,dp[i-1]]
    class Solution {
        public int maxProfit(int[] prices) {
            int[] dp = new int[prices.length];
            //记录第i天之前的最小股票价格,用于计算dp[i]的最小值
            int min = prices[0];
            for (int i = 1; i < prices.length; i++) {
                dp[i] = Math.max(prices[i] - min, dp[i - 1]);
                min = Math.min(min, prices[i]);
            }
            return dp[prices.length - 1];
        }
    }
    //空间复杂度优化
    class Solution {
        public int maxProfit(int[] prices) {
            int ans = 0;
            int min = prices[0];
            for (int i = 1; i < prices.length; i++) {
                ans = Math.max(prices[i] - min, ans);
                min = Math.min(min, prices[i]);
            }
            return ans;
        }
    }
    
  • 解题模板
    • dp[i][k][s] 表示第i天,最多购买了k次购票的利润。s代表是否持有股票
    • 状态转换图:71XEV_9T`YZ@S6_WIRYHK@D.png
    • 状态转移方程:
      • dp[i][k][0]=MAX[dp[i1][k][0],dp[i1][k][1]+price[i]]dp[i][k][0] = MAX[dp[i-1][k][0],dp[i-1][k][1]+price[i]]
      • dp[i][k][1]=MAX[dp[i1][k][1],dp[i1][k1][1]price[i]]dp[i][k][1] = MAX[dp[i-1][k][1],dp[i-1][k - 1][1]-price[i]]
    • base case:
      • dp[1][...][0]=dp[...][0][0]=0dp[-1][...][0] = dp[...][0][0] = 0
      • dp[1][...][1]=dp[...][0][1]=infinitydp[-1][...][1] = dp[...][0][1] = -infinity
    class Solution {
        public int maxProfit(int[] prices) {
            int ans = 0;
            int[][] dp = new int[prices.length][2];
            dp[0][0] = 0;
            //base case 初始持有股票的收益为-prices[0],
            dp[0][1] = -prices[0];
            for (int i = 1; i < prices.length; i++) {
                //上一次持有股票本次未操作   
                //上一次未持有股票,本次购买(仅能购买一次,简化为-prices[i])
                dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
                //上一次未持有股票,没有操作   上一次持有股票,本次抛出
                dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            }
            return dp[prices.length - 1][0];
        }
    }
    

2、122. 买卖股票的最佳时机 II

  • 思路:
    • 采用股票问题解题套路k没有次数限制
    • 结束条件是 dp[天数][0]dp[天数][0],未持有股票肯定是利润最高的
    class Solution {
        public int maxProfit(int[] prices) {
            int len = prices.length;
            int[][] dp = new int[len][2];
            dp[0][0] = 0;
            dp[0][1] = -prices[0];
            for (int i = 1; i < len; i++) {
                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 - 1][0] - prices[i]);
            }
            return dp[len - 1][0];
        }
    }