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

发布时间 2023-04-27 16:25:32作者: xiazichengxi

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

> 贪心解法

假如第0天买入,第3天卖出,那么利润为:prices[3] - prices[0]。

相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

此时就是把利润分解为每天为单位的维度,而不是从0天到第3天整体去考虑!其实我们需要收集每天的正利润就可以,收集正利润的区间,就是股票买卖的区间,而我们只需要关注最终利润,不需要记录区间。

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

> 动态规划

每天都有三种动作:买入(buy)、卖出(sell)、无操作(rest)。

因为不限制交易次数,因此交易次数这个因素不影响题目,不必考虑。DP Table 是二维的,两个维度分别是天数(0,1,...,n-1)和是否持有股票(1 表持有,0 表不持有)。

状态转移方程
Case 1,今天我没有股票,有两种可能:

昨天我手上就没有股票,今天不做任何操作(rest);
昨天我手上有一只股票,今天按照时价卖掉了(sell),收获了一笔钱
Case 2,今天持有一只股票,有两种可能:

昨天我手上就有这只股票,今天不做任何操作(rest);
昨天我没有股票,今天按照时价买入一只(sell),花掉了一笔钱
综上,第 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])
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n, vector<int>(2, 0));
        dp[0][0] = 0; //不持股票
        dp[0][1] -= prices[0]; // 持股票
        for(int i = 1; i < n;i++){
            dp[i][0] = std::max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1] = std::max(dp[i-1][1],dp[i-1][0]-prices[i]);
        }
        return dp[n-1][0];
    }
};