二刷代码随想录训练营Day 41|力扣121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III

1.买卖股票的最佳时期

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(2, 0));
        // dp[i][0] 表示第i填持有股票的最大利润 (持有 != 当天买入)
        // dp[i][1] 表示第i填不持有股票的最大利润
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i = 1; i < prices.size(); i++){
            dp[i][0] = max(dp[i - 1][0], -prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
        }
        return dp[prices.size() - 1][1];
    }
};

 note:

dp数组的含义:dp[i][0]表示当天持有股票的最大利润;dp[i][1]表示当天不持有股票的最大利润

递推公式:

        dp[i][0] = max(dp[i -1][0 ],dp[i - 1][1]) 第i天持有股票,有两种可能,一种是前一天就已经是持有股票的状态了,第i天只是去保持这种状态;另一种是,当天才去购买股票,由于题上说只能购买一支股票,因此直接在0的基础上-prices[i]

        dp[i][1] = max(dp[i - 1][1],dp[i - 1][0] + prices[i] ),第i天不持有股票,也有两者可能,可能前一天就已经不持有股票了,第i天只是保持这种状态;另一种是,当天把股票卖出了,这种情况的前提是前一天已经持有股票了,因此为dp[i - 1][0] + prices[i]

dp数组的初始化:根据递推公式,我们需要初始化dp[0][0]和dp[0][1],按照dp数组的含义进行初始化即可,dp[0][0] = -prices[0] dp[0][1] = 0

遍历顺序:正序遍历,因为后面的元素的求值依赖于前一个元素

2.买卖股票的最佳时期2

 代码随想录

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(2,0));
        // dp[i][0] 表示第i天持有股票的最大利润
        // dp[i][1] 表示第i天不持有股票的最大利润
        dp[0][0] = -prices[0];
        dp[0][1] = 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]);
        }
        return dp[prices.size() - 1][1];
    }
};

note:

和上题的区别在于,dp[i][0]的求法,因为本题不再限制只能购买一支股票,因此不需要在0的基础上当天购入股票了,而是在前一天不持有股票的基础上卖出股票,也就是dp[i - 1][1] - prices[i]

其它的都一样,就不写了。

3.买卖股票的最佳时期3

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(),vector<int>(5,0));
        // dp[i][0] 没有进行任何操作
        // dp[i][1] 第一次持有股票
        // dp[i][2] 第一次不持有股票
        // dp[i][3] 第二次持有股票
        // dp[i][4] 第二次不持有股票
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[0];
        for(int i = 1; i < prices.size(); i++){
            dp[i][1] = max(dp[i - 1][1], -prices[i]);
            dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }
        return dp[prices.size() - 1][4];
    }
};

 note:

dp数组的含义:因为这道题限制最多买两支股票,因此本题的状态要设置得多一点,区分开第一次买入和第二次买入的情况。

        // dp[i][0] 没有进行任何操作

        // dp[i][1] 第一次持有股票

        // dp[i][2] 第一次不持有股票

        // dp[i][3] 第二次持有股票

        // dp[i][4] 第二次不持有股票

递推公式:总体都是一个思路,要不保持前一天的同样的状态,要不去在前一天的某种状态的基础上,去在当天进行改变。

            dp[i][1] = max(dp[i - 1][1], -prices[i]);

            dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);

            dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);

            dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);

初始化:dp[0][0] = 0 dp[0][i] = - prices[0] dp[0][2] = 0 dp[0][3] = -prices[0] dp[0][4] = 0

遍历顺序:正序遍历,因为后面的元素的求值依赖于前一个元素

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值