121.买卖股票的最佳时机

在这道题目要求计算单次买卖能得到的最大利润,单次买卖的最大利润首先想到寻找最低股价买入,然后在最高股价时卖出。但是如果最低股价出现在最高股价的后面(时间上)呢?因此我们修改求解方法,单次买卖的最大利润需要寻找最低股价买入,然后在最低股价之后的天数中寻找最高股价时卖出;或者先寻找最高股价,然后从最高股价向前寻找最低股价。
在这道题目中,我们可以假设每一天都存在两种状态,持有股票和不持有股票。我们获取利润的过程也就是从不持有股票到持有股票(买入),再到不持有股票的过程(卖出)。因此我们有两种操作,买入和卖出,同时想到我们可以保持原有状态不操作,因此还有保持操作。
当天不持有股票的现金=MAX(前一天不持有股票的现金(保持)+(前一天持有股票的现金+当天股价)(卖出))
当天持有股票的现金=MAX(前一天持有股票的现金(保持)+(前一天不持有股票的现金-当天股价)(卖出))
更进一步,因为本题只允许单次买卖,所有前一天不持有股票的现金始终为0。经过化简可以将,当天不持有股票的现金等价于最大利润,初始为0代表不进行买卖时的利润是0不可能更低。当天持有股票的现金等价于最低买入价格,因为不发生多次买卖。
画出状态变化图辅助理解:

|
第i天 |
股票价格 |
买入 |
卖出 |
|
0 |
0 | ||
|
0 |
7 |
-7 |
0 |
|
1 |
1 |
max(-1, -7)=-1 |
max(-7+1, 0)=0 |
|
2 |
5 |
-1 |
4 |
|
3 |
3 |
-1 |
2 |
|
4 |
6 |
-1 |
5 |
|
5 |
4 |
-1 |
3 |
给出leetcode提交代码,代码参考代码随想录。
// leetcode上提交的代码
class Solution {
public:
int maxProfit(vector<int>& prices)
{
vector<int> dp(2, 0);
dp[0]=-prices[0]; // 对第0天初始化,仅考虑买入,因为无法卖出
for(int i=1;i<prices.size();i++)
{
// 找最低买入价格
int temp = max(dp[0], -prices[i]);
// 找最高买卖利润
dp[1]=max(dp[1], dp[0]+prices[i]);
dp[0]=temp;
}
return dp[1];
}
};
122.买卖股票的最佳时机
相比121,本题中允许多次买卖。所以不能认为前一天不持有股票时的现金始终为0,应该随买卖进行不断变化,给出状态图。

805

被折叠的 条评论
为什么被折叠?



