代码随想录算法训练营第四十九天【动态规划part10】 | 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

121. 买卖股票的最佳时机

题目链接:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

求解思路:

动规五部曲

  1. 确定dp数组及其下标含义:使用一个二维数组dp[i][2],dp[i][0]代表持有股票的最大收益,dp[i][1]代表不持有股票的最大收益;注意“持有”不代表当天买入,可能是之前的某一天就买入了,“不持有”同理
  2. 确定递推公式:如果当天持有股票,则股票可能是之前就买好了,或者是当天买的,递推公式取两者较大值,即dp[i][0] = max(dp[i - 1][0], -prices[i]);如果当天不持有股票,则股票可能是之前就卖出了,也可能是当天才卖出,取两者较大值,即dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
  3. dp数组的初始化:dp[0][0]表示第0天持有股票,dp[0][0] -= prices[0];dp[0][1]表示第0天不持有股票,dp[0][1] = 0
  4. 确定遍历顺序:从前向后
  5. 举例推导dp数组:以[7,1,5,3,6,4]为例,dp数组状态如下

代码随想录算法训练营第四十九天【动态规划part10】 | 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II_第1张图片

代码:

class Solution {
public:
    int maxProfit(vector& prices) {
        if (prices.size() == 0) return 0;
        vector> dp(prices.size(),vector(2));
        // 0为当天持有该股票,1为当天不持有
        dp[0][0] = -1 * prices[0];
        dp[0][1] = 0;
        for (int i = 1; i < prices.size(); i++){
            // 当天持有股票,可能是之前买的,可能是今天买的
            dp[i][0] = max(dp[i-1][0], -1 * prices[i]);
            // 当天未持有股票,可能是之前卖了,也可能是今天卖了
            dp[i][1] = max(dp[i-1][1], prices[i] + dp[i-1][0]);
        }
        return dp[prices.size()-1][1];
    }
};

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

题目链接:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

求解思路:

和前一题唯一不一样的地方在于当天持有股票的所得金额,即dp[i][0]的递推公式

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来:第i-1天就持有股票,则保持现状,即dp[i][0] = dp[i-1][0];第i天买入股票,则所得现金为昨天不持有股票的现金减去今天的股票价格,即 dp[i - 1][1] - prices[i]

代码:

class Solution {
public:
    int maxProfit(vector& prices) {
        vector> dp(prices.size(), vector(2,0));
        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];
    }
};

你可能感兴趣的:(算法训练,动态规划,算法)