Day49 动规 121 122

90 阅读1分钟

121. 买卖股票的最佳时机

心得

  • 贪心,找最小,然后找最大波峰,AC

题解

  • 可以用动规通过i天是否持只依赖前一天状态来判断,通过当前是否持有,持有卖出通过前一状态递推
// 贪心,时间复杂度O(n),空间O(1)
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minPrice = INT_MAX;
        int result = 0;
        for (int i = 0; i < prices.size(); i++) {
            minPrice = min(minPrice, prices[i]);
            result = max(prices[i] - minPrice, result); 
        }
        return result;
    }
};
// 动规思路 时间O(N)空间(N)
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int length = prices.size();
        if (length == 0) return 0;
        vector<vector<int>> dp(length, vector<int>(2)); // 第i天的持有股票与否得到的最大现金
        dp[0][0] -= prices[0];
        dp[0][1] = 0;

        for (int i = 1; i < length; i++) {
            dp[i][0] = max(dp[i - 1][0], -prices[i]);// 第i天持有股票所得的最大现金
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);// 第i天不持有股票所得最大现金
        }
        return dp[length - 1][1]; // 卖出肯定利润高

    }
};
// 动规优化空间,只取决前一状态,可以将空间复杂度压缩N到1
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int length = prices.size();
        if (length == 0) return 0;
        vector<vector<int>> dp(2, vector<int>(2)); // 第i天的持有股票与否得到的最大现金
        dp[0][0] -= prices[0];
        dp[0][1] = 0;

        for (int i = 1; i < length; i++) {
            dp[i % 2][0] = max(dp[(i - 1) % 2][0], -prices[i]);// 第i天持有股票所得最大现金
            dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);// 第i天不持有股票所得最大现金
        }
        return dp[(length - 1) % 2][1]; // 卖出肯定利润高

    }
};

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

心得

  • 基本同前一天,唯一区别在于第i天持有的买入情况即dp[i][0]递推式不一样,此时可以多次买入卖出

题解

// 动规思路 时间O(N)空间(N)
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int length = prices.size();
        if (length == 0) return 0;
        vector<vector<int>> dp(length, vector<int>(2)); // 第i天的持有股票与否得到的最大现金
        dp[0][0] -= prices[0];
        dp[0][1] = 0;

        for (int i = 1; i < length; i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);// 第i天持有股票所得的最大现金
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);// 第i天不持有股票所得最大现金
        }
        return dp[length - 1][1]; // 卖出肯定利润高

    }
};
// 动规优化空间,只取决前一状态,可以将空间复杂度压缩N到1
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int length = prices.size();
        if (length == 0) return 0;
        vector<vector<int>> dp(2, vector<int>(2)); // 第i天的持有股票与否得到的最大现金
        dp[0][0] -= prices[0];
        dp[0][1] = 0;

        for (int i = 1; i < length; i++) {
            dp[i % 2][0] = max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]);// 第i天持有股票所得最大现金
            dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);// 第i天不持有股票所得最大现金
        }
        return dp[(length - 1) % 2][1]; // 卖出肯定利润高

    }
};