Day51 动规 309 714

39 阅读1分钟

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

心得

  • 想的是通过新增最大卖出次数,也就n/2来遍历得到最大值,增加一层循环

题解

  • 通过新增冷冻期状态在状态转移方程中,进行递推,其实就是在之前股票问题中将不持有的合并状态拆分出来,此时考虑到冷冻期因素,直接合并不好写统一公式,所以拆出来细分逻辑
  • 初始化时,根据递推公式和想要的数值推理一般0或者目标数组其中的值,作为基值,代入合理推理得到即可
  • 时间复杂度O(n) 空间复杂度O(n),空间可以优化到O(2)(4)
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n == 0) return 0;
        // dp[i][j] 在第i天状态j的最大现金,j可以分为4种状态
        vector<vector<int>> dp(n, vector<int>(4, 0));
        dp[0][0] -= prices[0]; // 第0天持有即买入,其他根据公式推理
        for (int i = 1; i < prices.size(); i++) {
            // 状态1 保持持有股票状态
            dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]));
            // 状态2 保持之前卖出状态
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
            // 状态3 今天卖出
            dp[i][2] = dp[i - 1][0] + prices[i]; 
            // 状态4 冷冻期
            dp[i][3] = dp[i - 1][2];
        }
        return max(dp[n - 1][1], max(dp[n - 1][2], dp[n - 1][3])); // 卖出才是最大收益
    }
};

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

心得

  • 与之前差别在于,卖出时考虑手续费,同时最后结果考虑持有和不持有即可能利润小于手续费导致持有可能会利润更大
  • 时间O(N),空间O(N),当然可以滚动压缩空间复杂度

题解

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        if (prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
        dp[0][0] -= prices[0];
        for (int i = 1; i < prices.size(); i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
        } 
        return max(dp[prices.size() - 1][0], dp[prices.size() - 1][1]);
    }
};