代码随想录算法训练营
Day41 代码随想录算法训练营第 41 天 | LeetCode121. 买卖股票的最佳时机 LeetCode122. 买卖股票的最佳时机ii LeetCode123. 买卖股票的最佳时机iii
目录
前言
LeetCode121. 买卖股票的最佳时机
LeetCode122. 买卖股票的最佳时机ii
LeetCode123. 买卖股票的最佳时机ii
一、LeetCode121. 买卖股票的最佳时机
1.题目链接
2.思路
(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:j=0表示持有股票 j=1表示未持有股票
(2)转移方程
-
dp[i][0]=max(dp[i-1][0],-prices[i]);
上一次没有持有股票,说明之前从没持有过股票,现金是0;
上一次持有股票,说明第i天卖掉,增加prieces[i]元现金
2) dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
上一次持有股票,说明第i天没有变动
(3)初始化
dp[0][0]=-prices[0];—第一天买入dp[0][1]=0;------现金没有变化
3.题解
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size();
int dp[n][2];
dp[0][0]=-prices[0];
//0--持有股票 1--未持有股票
dp[0][1]=0;
for(int i=1;i<n;i++)
{
dp[i][0]=max(dp[i-1][0],-prices[i]);//上一次没有持有股票,说明之前从没持有过股票
dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
}
return dp[n-1][1];
}
};
二、LeetCode122. 买卖股票的最佳时机ii
1.题目链接
2.思路
(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:j=0表示持有股票 j=1表示未持有股票
(2)转移方程
- dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]);
上一次没有持有股票,之前可能持有过股票,现金可能变化过;
上一次持有股票,说明第i天卖掉,增加prieces[i]元现金
2) dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
上一次持有股票,说明第i天没有变动
(3)初始化
dp[0][0]=-prices[0];—第一天买入
dp[0][1]=0;------现金没有变化
3.题解
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size();
int dp[n][2];
dp[0][0]=-prices[0];
dp[0][1]=0;
for(int i=1;i<n;i++)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]);
dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
}
return dp[n-1][1];
}
};
三、LeetCode123. 买卖股票的最佳时机iii
1.题目链接
2.思路
(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:
j=0表示从未持有股票
j=1表示第一次持有股票
j=2表示第一次卖出股票
j=3表示第二次持有股票
j=4表示第二次卖出股票
(2)转移方程
1)dp[i][0]=dp[i-1][0];
从未持有过股票,现金不可能变化过
2 ) dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);
上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
上一次第一次持有股票,说明第i天没有变动
3)dp[i][2]=max(dp[i-1][1]+prices[i],dp[i-1][2]);
上一次第一次持有股票,说明第i天卖出,增加prieces[i]元现金;
上一次第一次卖出股票,说明第i天没有变动
4) dp[i][3]=max(dp[i-1][2]-prices[i],dp[i-1][3]);
上一次第一次卖出股票,说明第i天买入,减少prieces[i]元现金;
上一次第二次持有股票,说明第i天没有变动
5) dp[i][4]=max(dp[i-1][3]+prices[i],dp[i-1][4]);
上一次第二次持有股票,说明第i天卖出,增加prieces[i]元现金;
上一次第二次卖出股票,说明第i天没有变动
(3)初始化
dp[0][0]=0;------现金没有变化
dp[0][1]=-prices[0];—第一天买入;
dp[0][2]=0;------第一天先买后卖,现金没有变化
dp[0][3]=-prices[0];—第一天买入,卖出,买;
dp[0][4]=0;—第一天买入,卖,买,卖;
(4)返回:最终不持有股票肯定比最终持有股票的情况现金多
3.题解
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size();
int dp[n][5];
/*
0--从未持有股票
1--第一次持有
2--第一次卖出后
3--第二次持有
4--第二次卖出后
*/
dp[0][0]=0;
dp[0][1]=-prices[0];
dp[0][2]=0;
dp[0][3]=-prices[0];//第一天可以买卖两次
dp[0][4]=0;
for(int i=1;i<n;i++)
{
dp[i][0]=dp[i-1][0];
dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);
dp[i][2]=max(dp[i-1][1]+prices[i],dp[i-1][2]);
dp[i][3]=max(dp[i-1][2]-prices[i],dp[i-1][3]);
dp[i][4]=max(dp[i-1][3]+prices[i],dp[i-1][4]);
}
int t= max(dp[n-1][0],dp[n-1][2]);
return max(t,dp[n-1][4]);
}
};