309. Best Time to Buy and Sell Stock with Cooldown
解题思路
可以分两种状态来维护,两个数组hold[]持有股票的最大收益和sold[]卖出股票的最大收益,持有股票状态与卖出股票状态的改变会相互影响。
Solution: DP (动态规划)
hold[i] = max(hold[i-1], sold[i-2] – price[i])
(解释:持有股票的最大收益是到昨天为止的持有最大收益和到前天为止的卖出股票的最大收益减去今天买股票花的钱,两者中收益大的,如果取左项表示不操作收益更大,右项是选择买入,i-2表示需要cooldown一天)
sold[i] = max(sold[i-1], hold[i-1] + price[i])
(同样:卖出股票的最大收益是到昨天卖出最大收益和到昨天持有股票的最大收益加上今天卖股票赚的钱,两者中收益大的。其实要么不卖(左项),要么卖(右项))
Init: hold[0] = - price[0],
sold[0] = 0, sold[1-2] = 0
Answer: sold[i]
Time Complexity: O(n)
状态图
用这个例子根据算法步骤计算
[1, 2, 3, 0, 2]
[buy, sell, cooldown, buy, sell]
price | hold | sold |
---|---|---|
1 | -1 | 0 |
2 | -1 | 1 |
3 | -1 | 2 |
0 | 1 | 2 |
2 | 1 | 3 |
取最后项sold[i] = 3
完整代码
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() <= 1) return 0;
vector<int> hold(prices.size(), 0), sold(prices.size(), 0);
hold[0] = -prices[0]; sold[0] = 0;
hold[1] = max(hold[0], -prices[1]); sold[1] = max(0, hold[0] + prices[1]);
for(unsigned int i = 2; i < prices.size(); ++i)
{
hold[i] = max(hold[i-1], sold[i-2] - prices[i]);
sold[i] = max(sold[i-1], hold[i-1] + prices[i]);
}
return sold[prices.size()-1];
}
};