文章链接:121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III
121.买卖股票的最佳时机
思路:
1.dp数组的含义:dp[i][0]表示持有股票时的最大金额,dp[i][1]表示不持有股票时的最大金额。
2.递推公式:
dp[i][0] = max(dp[i - 1][0], -prices[i]); // 第i - 1天 持有(即不是第i天买的) 或者 第i天买入
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]); // 第i - 1天 不持有(即不是第i天卖的) 或者 第i天卖出
3.dp数组初始化:
dp[0][0] = -prices[0];
dp[0][1] = 0;
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) return 0;
vector<vector<int>> dp(prices.size() + 1, vector<int> (3, 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], -prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[prices.size() - 1][1];
}
};
122.买卖股票的最佳时机II
思路:
与上一题的区别:本题股票可以买卖多次;
与上一题只有递推公式不同:
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 len = prices.size();
vector<vector<int>> dp(len, vector<int>(2, 0));
dp[0][0] -= prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
// 注意这里是和121. 买卖股票的最佳时机唯一不同的地方。
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[len - 1][1];
}
};
123.买卖股票的最佳时机III
思路:
与上两题的区别:至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。
1.dp数组的含义:
- 没有操作 (其实我们也可以不设置这个状态)
- 第一次持有股票
- 第一次不持有股票
- 第二次持有股票
- 第二次不持有股票
dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。
2.递推公式:
dp[i][0] = dp[i - 1][0];
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - 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]);
3.dp数组初始化:
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0; // 第一天买入和卖出
dp[0][3] = -prices[0]; // 第一天买入->卖出 ->买入
dp[0][4] = 0; // 第一天买入->卖出 ->买入->卖出
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0) return 0;
vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
dp[0][1] = -prices[0];
dp[0][3] = -prices[0];
for (int i = 1; i < prices.size(); i++) {
dp[i][0] = dp[i - 1][0];
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - 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]; // 直接返回第4中状态即可(第2种状态包含在第4种中)
}
};