LeetCode 309.最佳买卖股票的时机包含冷冻期

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目:给定一个价格数组,数组中元素代表每一天的股票价格,现要设计一个算法算出最大利润。在满足以下要求的前提下,可以完成即可能多的交易:

  • 卖出股票后,第二天为冷冻期,该天不能买入股票。
  • 不能同时持有多只股票,即再次购买前必须出售当前已有股票。

解题思路

之前做过一题买卖股票的最佳时机,对应LeetCode 121。那题的解决方法是动态规划,其中动态规划数组dp[i]代表的是前i天的最低价格,之后遍历每天的股票将该天价格减去之前最低价即可。

本题的思路也是动态规划,但多了一个冷冻期。那么所有可能的收益情况就变成:

  • 当天持有股票的收益,我们假设以dp[i][0]来表示。
  • 当天不持有股票且处于冷冻期的收益,我们假设以dp[i][1]来表示。
  • 当前不持有股票且不处于冷冻期的收益,我们假设以dp[i][2]来表示。

那么上述情况就等价于:

  • dp[i][0] 当前天持有股票的收益 = max(前一天持有股票的收益,当前他买入股票的收益) d p [ i ] [ 0 ] = m a x ( d p [ i 1 ] [ 0 ] , d p [ i 1 ] [ 2 ] p r i c e s [ i ] ) dp[i][0] = max(dp[i-1][0], dp[i-1][2]-prices[i])
  • dp[i][1] 当前天不持有股票且处于冷冻期的收益 = 当前天卖出了股票 d p [ i ] [ 1 ] = d p [ i 1 ] [ 0 ] + p r i c e s [ i ] dp[i][1] = dp[i-1][0] + prices[i]
  • dp[i][2] 当前天不持有股票且不处于冷冻期的收益 = max(前一天不持有股票且处于冷冻期, 前一天不持有股票且不处于冷冻期) d p [ i ] [ 2 ] = m a x ( d p [ i 1 ] [ 1 ] , d p [ i 1 ] [ 2 ] ) dp[i][2] = max(dp[i-1][1], dp[i-1][2])

最后一天的情况就是当天不持有股票但无法确定是否处于冷冻期,有了以上分析,可得代码如下:

public int maxProfit(int[] prices) {
    /**
         * dp[i][0] 当前天持有股票的收益 = max(前一天持有股票的收益,当前他买入股票的收益)
         *      dp[i][0] = max(dp[i-1][0], dp[i-1][2]-prices[i])
         * dp[i][1] 当前天不持有股票且处于冷冻期的收益 = 当前天卖出了股票
         *      dp[i][1] = dp[i-1][0] + prices[i]
         * dp[i][2] 当前天不持有股票且不处于冷冻期的收益 = max(前一天不持有股票且处于冷冻期, 前一天不持有股票且不处于冷冻期)
         *      dp[i][2] = max(dp[i-1][1], dp[i-1][2])
         */
    int len = prices.length;
    int[][] dp = new int[len][3];
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    dp[0][2] = 0;
    for(int i=1;i<len;i++){
        dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2]-prices[i]);
        dp[i][1] = dp[i-1][0] + prices[i];
        dp[i][2] = Math.max(dp[i-1][1], dp[i-1][2]);
    }
    // 最终肯定是不持有股票是不知道是否处于冷冻期
    return Math.max(dp[len-1][1], dp[len-1][2]);
}
复制代码

上述代码时间复杂度和空间复杂度都是 O ( n ) O(n)

おすすめ

転載: juejin.im/post/7076638631334510599
おすすめ