目录
买卖股票的最佳时机
买卖股票的最佳时机III
买卖股票的最佳时机 IV
买卖股票的最佳时机 II
买卖股票的最佳时机含手续费
买卖股票的最佳时机含冷冻期
买卖股票的最佳时机
121. 买卖股票的最佳时机
buy:手上有股票的最大收益
sell:手上没有股票的最大收益
i:到第 i 天时候的最大收益
j:完成了第 j 次交易时候的最大收益
解释:图中的 -∞ 是 INT_MIN >> 1
buy[i] = max(昨天的持有时最大收益,昨天空手时最大收益)
sell[i] = max(昨天空手时最大收益,昨天持有时最大收益 + 当天可以出售获得的价格)
理解:对 i j 的理解最重要,完成0 比交易,那么buy只能买一次,后序一定是前面的某次价格最便宜的,sell 0 比交易 那就都是0 ;
对于buy完成一笔交易的第一天和第二天来说一定是 取不到的(那就初始化成-INT_MAX,右移一位,此题在buy[1][1]时候越界)因为你第一天买的要到第二天才可以卖,第三天才能重新买入
对于sell完成一笔交易也就是第二天才能有值
重点:如果对sell和buy都初始化为0,不然会在第一次交易出现问题,导致后序不对,在buy[1][1] 0元就可以手上持有股票,对应于sell来说直接就可以当天卖掉
参考代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<vector<int>> buy(n, vector<int>(2, INT_MIN >> 1)), sell(n, vector<int>(2, INT_MIN >> 1));
buy[0][0] = -prices[0];
sell[0][0] = 0;
for(int i = 1; i < n; i++)
{
for(int j = 0; j < 2; j++)
{
buy[i][j] = max(buy[i - 1][j], sell[i - 1][j] - prices[i]);
sell[i][j] = sell[i - 1][j];
if(j == 1)
sell[i][j] = max(sell[i][j], buy[i - 1][j - 1] + prices[i]);
}
}
return max(sell[n - 1][0], sell[n - 1][1]);
}
};
买卖股票的最佳时机III
123. 买卖股票的最佳时机 III
和上题一样buy[4][2] 第5天才有值,前面4天,两买两卖
参考代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
// vector<vector<int>> buy(n, vector<int>(3)), sell(n, vector<int>(3));
vector<vector<int>> buy(n, vector<int>(3, INT_MIN >> 1));
auto sell = buy;
buy[0][0] = -prices[0], sell[0][0] = 0;
for(int i = 1; i < n; i++)
{
for(int j = 0; j < 3; j++)
{
buy[i][j] = max(buy[i - 1][j], sell[i - 1][j] - prices[i]);
// sell[i][j] = max(sell[i - 1][j], buy[i - 1][j - 1] + prices[i]);
sell[i][j] = sell[i - 1][j];
if(j > 0)
sell[i][j] = max(sell[i][j], buy[i - 1][j - 1] + prices[i]);
}
}
return max(sell[n - 1][0], max(sell[n - 1][1], sell[n - 1][2]));
}
};
买卖股票的最佳时机 IV
188. 买卖股票的最佳时机 IV
参考代码
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
// vector<vector<int>> buy(n, vector<int>(3)), sell(n, vector<int>(3));
vector<vector<int>> buy(n, vector<int>(k + 1, INT_MIN >> 1));
auto sell = buy;
buy[0][0] = -prices[0], sell[0][0] = 0;
for(int i = 1; i < n; i++)
{
for(int j = 0; j <= k; j++)
{
buy[i][j] = max(buy[i - 1][j], sell[i - 1][j] - prices[i]);
// sell[i][j] = max(sell[i - 1][j], buy[i - 1][j - 1] + prices[i]);
sell[i][j] = sell[i - 1][j];
if(j > 0)
sell[i][j] = max(sell[i][j], buy[i - 1][j - 1] + prices[i]);
}
}
int ret = 0;
for(int i = 0; i <= k; i++)
ret = max(ret, sell[n - 1][i]);
return ret;
}
};
买卖股票的最佳时机 II
122. 买卖股票的最佳时机 II
区别于上三题,就是无限次数,对于无限次数的体现就是sell[i - 1] - prices[i]和buy[i - 1] + prices[i]
只能手持一个股票的体现:buy[0] = -prices[0]和buy[i - 1]
参考代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<int> buy(n), sell(n);
buy[0] = - prices[0];
for(int i = 1; i < n; i++)
{
buy[i] = max(buy[i - 1], sell[i - 1] - prices[i]);
sell[i] = max(sell[i - 1], buy[i - 1] + prices[i]);
}
return sell[n - 1];
}
};
买卖股票的最佳时机含手续费
714. 买卖股票的最佳时机含手续费
重点:对于fee的位置
①fee一定不能在buy[i - 1] 或 sell[i - 1]后面,因为这两个表示的是一个状态,不是购买或者卖出的一个点
②在购买时减掉fee:sell[i - 1] - prices[i] - 2,刚开始我只改了这里,很奇怪为什么过不了?通过样例发现结果就多了一个fee,
那我想着在返回的时候减掉就行,但是这时候又会返回负数
那么再改返回值:sell[n - 1] - fee >= 0 ? sell[n - 1] - fee : 0;
结果出现了不用多减fee???
之后我终于发现了是因为buy[0]的原因,在买入的时候就要减掉fee第一次并没有减,
难点:能过的样例是因为没有用到prices[0],相同的prices不同的fee也会导致结果异常,下面的代码,发现取不到1,是比较的(-2 ,-3)了实际应该是比较(-4, -3) 这就是问题所在
参考代码1
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
vector<int> buy(n), sell(n);
buy[0] = -prices[0];
for(int i = 1; i < n; i++)
{
buy[i] = max(buy[i - 1], sell[i - 1] - prices[i]);
sell[i] = max(sell[i - 1], buy[i - 1] + prices[i] - fee);
}
return sell[n - 1];
}
};
参考代码2
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
vector<int> buy(n), sell(n);
buy[0] = -prices[0] - fee;
for(int i = 1; i < n; i++)
{
buy[i] = max(buy[i - 1], sell[i - 1] - prices[i] - fee);
sell[i] = max(sell[i - 1], buy[i - 1] + prices[i]);
}
return sell[n - 1];
}
};
买卖股票的最佳时机含冷冻期
309. 买卖股票的最佳时机含冷冻期
通过freeze[i - 1]来隔一天冷冻期为 1 天
参考代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<int> buy(n), sell(n), freeze(n);
buy[0] = -prices[0];
for(int i = 1; i < n; i++)
{
buy[i] = max(buy[i - 1], sell[i - 1] - prices[i]);
sell[i] = max(sell[i - 1], freeze[i - 1]);
freeze[i] = buy[i - 1] + prices[i];
}
return max(sell[n - 1], freeze[n - 1]);
}
};