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初始化:
可进行空间优化。
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,所以今天我就持有股票了。