力扣-股票买卖专题

1.只能买卖一次:121. 买卖股票的最佳时机。求最大差值。

 贪心思想:求最大价格差,针对每个更低价,去找它后面的最大值,求最大差值;

2.无限制:122. 买卖股票的最佳时机 II。最典型的问题,dp和贪心都可解。

贪心思想:求所有累计后-前的差值和

dp思想:dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润,那么状态更新公式:

//max(前一天也不持有股票,前一天有股票+今天卖出)
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
//max(前一天有股票,前一天无股票+今天买入)
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
//base case
dp[0][0]=0;
dp[0][1]=-prices[0];

由于i只依赖于i-1,所以可以进行空间优化

3.含手续费:714. 买卖股票的最佳时机含手续费

//可以在买入的时候计算手续费,也可以在卖出时计算手续费。

//max(前一天也不持有股票,前一天有股票+今天卖出)
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
//max(前一天有股票,前一天无股票+今天买入)
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]-fee);//买入时算上手续费
//base case
dp[0][0]=0;
dp[0][1]=-prices[0]-fee;//买入时计算手续费

可以进行空间优化,只用两个变量来记录,不使用dp数组。

//当然官方也提供了贪心解法,当时学的时候就不太懂,现在也很难理解,所以就不看了。

4.带冷冻期:309. 最佳买卖股票时机含冷冻期。需要分三种情况,结束当天表示所获取的最大利润,状态转移。

//这个状态的判断挺难的,我来尝试写一下

dp[i][0]表示不持有股票,dp[i][1]表示持有股票,dp[i][2]表示第i天处于冷冻期

dp[i][0]=max(dp[i-1][0], dp[i-1][2], dp[i-1]+prices[i]);//前一天没买、前一天处于冷冻期、当天卖出

dp[i][1]=max(dp[i-1][2]-prices[i], dp[i-1][1]);//前一天处于冷冻期、前一天就拥有股票
//注:上面不能有dp[i-1][0]-prices[i],因为前一天卖出股票,那么当前一天就是冷冻期,是不能买的

dp[i][2]=dp[i-1][0];//前一天卖出 

//base case初始化:
  dp[0][1]=-prices[0];

可进行空间优化。

5.只能买卖两次:123. 买卖股票的最佳时机 III。有难度,dp[i][k][0]表示第i天交易k次不持有股票,不持有股票表示当天卖出,并且在买入时就使得k+1。

dp[i][k][0]表示第i天进行k次交易不持有股票的最大利润,dp[i][k][1]表示持有的最大利润。

//当买入时就计算交易次数
//前一天没有股票、前一天有股票+今天卖出(卖出不会增加交易次数)
dp[i][k][0]=max(dp[i-1][k][0],dp[i-1][k][1]+prices[i]);

//前一天有股票,前一天没有股票+买入股票(买入要计算交易次数)
dp[i][k][1]=max(dp[i-1][k][1],dp[i-1][k-1][0]-prices[i]);

//base case
dp[0][0][0]=0;
dp[0][0][1]=INT_MIN;//这种状态是不可能的
dp[0][1][0]=INT_MIN;//这种状态也不可能
dp[0][1][1]=-prices[0];

https://labuladong.gitbook.io/algo/bi-du-wen-zhang/tuan-mie-gu-piao-wen-ti,这个博客中将base case初始化为了INT_MIN,但是官解中初始化为了-prices[0],这两者有什么区别吗?我还是要继续看。

 

6.终极综合题目:188. 买卖股票的最佳时机 IV。指定完成k次交易,

 

 

7.参考

https://labuladong.gitbook.io/algo/dong-tai-gui-hua-xi-lie/1.5-qi-ta-jing-dian-wen-ti/tuan-mie-gu-piao-wen-ti

dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
              max(   选择 rest  ,             选择 sell      )

解释:今天我没有持有股票,有两种可能:
要么是我昨天就没有持有,然后今天选择 rest,所以我今天还是没有持有;
要么是我昨天持有股票,但是今天我 sell 了,所以我今天没有持有股票了。

dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
              max(   选择 rest  ,           选择 buy         )

解释:今天我持有着股票,有两种可能:
要么我昨天就持有着股票,然后今天选择 rest,所以我今天还持有着股票;
要么我昨天本没有持有,但今天我选择 buy,所以今天我就持有股票了。

 

posted @ 2020-12-22 13:59  lypbendlf  阅读(310)  评论(0编辑  收藏  举报