leetcode股票问题系列总结
首先我们对本题所有状态进行一次穷举
1 | for 状态1 in 状态1的所有取值: |
在这个问题里面,每天都有三种选择,也就是买入,卖出,无操作。但这三种操作是有顺序的,因为卖出必须在买入之后,买入必须在卖出之后,那么无操作的情况也要分两种,一种是持有股票选择了无操作,一种则是没有股票选择了无操作,我们可能对交易次数还有限制,也就是说你的买入是有前提限制的。
所以本类题目所有的状态其实有三个,第一个是天数,第二个是允许交易的最大次数,第三个则是当前的持有状态,在这里我们通过一个三维数组实现
1 | //这里第一个i代表天数,第二个k代表当前交易剩下的次数,第三0 or 1则代表了持有和未持有的两种状态。 |
那我们每天有哪些可能性呢?我们来列举一下
1 | profit[i][k][0] = max(profit[i-1][k][0], profit[i-1][k][1] + prices[i]) |
接下里就是整个框架的base case
1 | profit[-1][k][0] = 0 |
再整理一下,便可以得到整套系列题的通用解法
1 | base case: |
面对这道题
我们直接带入框架可得到
1 | profit[i][1][0] = max(profit[i-1][1][0], profit[i-1][1][1] + prices[i]) |
简化后,我们直接写出代码
1 | public static int maxProfit(int[] prices) { |
我们再来看看系列问题的第二题
这里有一个变化,就是不会对你的交易次数做限制,因此我们的代码变化一下
1 | public int maxProfit(int[] prices) { |
系列问题的第三题
在这里我们的交易次数被限制了,变成了2次,因此我们的引入k值。
1 | public int maxProfit(int[] prices) { |
最后一题
![批注 2020-08-08 151748](批注 2020-08-08 151748.png)
这里便不会限制你的交易次数了
本来我开始的解法是
1 | if(prices == null || prices.length == 0) |
但提交的时候发生了这件事
k为10亿!?
远远的超过了数组长度,也就是说,我可以无限交易,这样便可以不用讨论动态规划,直接退化贪心算法即可解决问题,k >= n / 2就可以,买入卖出毕竟需要两天
1 | public int maxProfit(int k, int[] prices) { |
参考