代码随想录Day53 | 股票买卖
121.买卖股票的最佳时机
文档讲解:代码随想录
视频讲解: 动态规划之 LeetCode:121.买卖股票的最佳时机1
状态
贪心->dp
之前使用的贪心算法,我们稍微修改
- dp数组
dp[j] 表示 第j天的可以赚得的最大金额 - 递推公式
如果第j天金额比记录的最小值小那么就为0,并且更新最小值
如果第j天金额比记录的最小值大,那么就比较dp[j-1]和prices[j]-minval的大小存储最大值。 - 初始化
初始全为0,最小值记录为第一个数 - 遍历顺序
从前向后 - 打印dp
class Solution {
public:
int maxProfit(vector<int>& prices) {
//记录最小值
int minval = prices[0];
vector<int> dp(prices.size(),0);
for(int i = 1;i<prices.size();i++)
{
if(prices[i] <= minval)
{
dp[i] = dp[i-1];
minval = prices[i];
}
else
{
dp[i] = max(dp[i-1],prices[i]-minval);
}
}
return dp[prices.size()-1];
}
};
动态规划
二维dp数组
-
dp数组
dp[j][0] 表示第i天持有股票时的最大金额
dp[j][1] 表示第i天不持有股票时的最大金额 -
递推公式
首先对于dp[j][0],由于只会购买一次,所以如果前一天持有股票那么dp[j][0] = dp[j-1][0]。如果前一天没有持有股票,则第j天购入,那么dp[j][0] = -prices[j]其次对于dp[j][1],如果第j-1天不持有股票那么dp[j][1] = dp[j-1][1]。如果第j天卖出股票那么dp[j][1] = dp[j-1][0]+prices[j]
-
初始化
dp[0][0] = -prices[0] dp[0][1] = 0 -
遍历顺序
从前往后 -
打印dp
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() == 0) return 0;
vector<vector<int>> dp(prices.size(),vector<int>(2));
dp[0][0] = -1* prices[0];
dp[0][1] = 0;
for(int i = 1;i<prices.size();i++)
{
dp[i][0] = max(dp[i-1][0],-1*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数组
-
dp数组
dp[j][0] 表示第i天持有股票时的最大金额
dp[j][1] 表示第i天不持有股票时的最大金额 -
递推公式
首先对于dp[j][0],由于只会购买一次,所以如果前一天持有股票那么dp[j][0] = dp[j-1][0]。如果前一天没有持有股票,由于前面已经卖出有金额或者为0则第j天购入,那么dp[j][0] = dp[j-1][1]-prices[j]其次对于dp[j][1],如果第j-1天不持有股票那么dp[j][1] = dp[j-1][1]。如果第j天卖出股票那么dp[j][1] = dp[j-1][0]+prices[j]
-
初始化
dp[0][0] = -prices[0] dp[0][1] = 0 -
遍历顺序
从前往后 -
打印dp
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() == 0) return 0;
vector<vector<int>> dp(prices.size(),vector<int>(2));
dp[0][0] = 0 - prices[0];
dp[0][1] = 0;
for(int i = 1;i<prices.size();i++)
{
//对于第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];
}
};
这两道题都是dp[j][1]的返回结果,因为最大金额一定是要抛出手中股票才会得到