309. Best Time to Buy and Sell Stock with Cooldown[Medium]
Description
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
- You may not engage in multiple transactions at the same time (ie, you
must sell the stock before you buy again). - After you sell your stock, you cannot buy stock on next day. (ie,
cooldown 1 day)
Example:
prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell]
Solution
这道题是Best Time to Buy and Sell Stock with Colldown的升级版。给出一个数字,第i个元素表示某只股票在第i天的价格。限制条件是,卖出后第二天不可以马上买入。可以多次交易,但是在买入股票之前必须卖出。
看了看好像应该先做Best Time to Buy and Sell Stock II,但是不要紧,DP问题就是找递推式子。
第i天的交易累积收益只和第i-1天、第i-2天有关。
sell[i]表示在第i天选择卖出的最大累积收益
buy[i]表示在第i天选择买入的最大累积收益
sell[i] = max(buy[i - 1] + prices[i], sell[i - 1] + (prices[i) - prices[i-1]))
buy[i] = max(sell[i - 2] - prices[i], buy[i - 1] - (prices[i) - prices[i-1]))
意思就是,
第i天选择卖出的最大收益 = max(第i-1天买入第i天卖出的最大累积收益,第i-1天卖出改为第i天卖出的最大累积收益【sell[i-1]-prices[i-1]+prices[i]】)
第i天选择买入的最大收益 = max(第i-2天卖出第i天买入的最大累积收益, 第i-1天买入改为第i天买入的最大累积收益【buy[i-1]+prices[i-1]-prices[i]】)
返回sell数组中的最大值即为答案。
需要注意的是初始化数组,由于循环从i = 2开始才不会越界所以要处理下标为0和1的时候的数据
buy[0] = -price[0];
buy[1] = -price[1];
sell[1] = (price[1] - price[0]) > 0 ? (price[1] -price[0]) : 0;
Complexity analysis
O(n)
Code
class Solution {
public:
int maxProfit(vector<int>& price) {
int maxPro = 0;
int curPro = 0;
int n = price.size();
if (n <= 1) {
return 0;
}
int buy[n] = {0};
int sell[n] = {0};
buy[0] = -price[0];
buy[1] = -price[1];
sell[1] = (price[1] - price[0]) > 0 ? (price[1] - price[0]) : 0;
maxPro = sell[1];
if (n == 2)
return sell[1];
for(int i = 2; i < n; i++) {
sell[i] = max(buy[i-1] + price[i], sell[i-1] + (price[i]-price[i-1]));
buy[i] = max(sell[i-2] - price[i], buy[i-1] - (price[i]-price[i-1]));
maxPro = max(maxPro, sell[i]);
}
return maxPro;
}
};