代码随想录day49 | 121. 买卖股票的最佳时机 122.买卖股票的最佳时机II

121. 买卖股票的最佳时机

题目|文章
image

思路

这道题可以用贪心算法和暴力解决,在此不讨论,只考虑动态规划的做法。

  1. 数组以及下标含义。
    dp[i][0]:手上持有股票时所能得到的最大金额
    dp[i][1]:手上没有持有股票时所能得到的最大金额
    理解这个含义的关键在于,dp[j][0]只考虑此时手中有没有股票,但是不考虑股票是什么时候买的
  2. 递推关系
    dp[i][0] = max(dp[i - 1][0], -prices[i]);
  • 原本手上有股票,那么就与之前情况相同
  • 原本手上没有股票,就要买一个股票
    dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
  • 原本手上没有股票,保持原状
  • 原本手上有股票,那么卖掉股票
  1. 初始化
    开始时,手中并没有股票,因此dp[0][1] = 0;
    需要买当天的股票手中才能持有股票,因此dp[0][0] = -prices[0];
  2. 遍历顺序
    按照天数从前向后遍历。

实现

点击查看代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(2,vector<int>(2,0));
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        for(int i = 1; i < prices.size(); i++) {
            dp[i%2][0] = max(dp[(i-1) % 2][0], -prices[i]);
            dp[i%2][1] = max(dp[(i-1) % 2][1], prices[i] + dp[(i-1) % 2][0]);
        }
        return dp[(prices.size() - 1) % 2][1];
    }
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

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

题目|文章
image

思路

本体与上一题唯一的区别在于可以重复购买,因此递推关系有所变化
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])

  • 原本手中有股票,那么无需购买,与之前相同
  • 原本手中无股票,那么需要购买当天的股票。与上一题的区别在于手中的金额也在变化。

实现

点击查看代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(), vector<int>(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];
    }
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
posted @ 2022-11-09 16:40  缩地  阅读(19)  评论(0)    收藏  举报