[LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期

Say you have an array for which the ith element is the price of a given stock on day i.html

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:java

  • 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:python

prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell]

买卖股票问题,这里多了一个冷却期,在卖出股票后的次日不能交易,必须隔一天才能在买。算法

须要维护三个一维数组buy, sell,和rest。其中:数组

buy[i]表示在第i天以前最后一个操做是买,此时的最大收益。优化

sell[i]表示在第i天以前最后一个操做是卖,此时的最大收益。url

rest[i]表示在第i天以前最后一个操做是冷冻期,此时的最大收益。spa

咱们写出递推式为:.net

buy[i] = max(rest[i-1] - price, buy[i-1])
sell[i] = max(buy[i-1] + price, sell[i-1])
rest[i] = max(sell[i-1], buy[i-1], rest[i-1])rest

上述递推式很好的表示了在买以前有冷冻期,买以前要卖掉以前的股票。一个小技巧是如何保证[buy, rest, buy]的状况不会出现,这是因为buy[i] <= rest[i], 即rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。

另外,因为冷冻期的存在,能够得出rest[i] = sell[i-1],这样,能够将上面三个递推式精简到两个:

buy[i] = max(sell[i-2] - price, buy[i-1])
sell[i] = max(buy[i-1] + price, sell[i-1])

作进一步优化,因为i只依赖于i-1和i-2,因此能够在O(1)的空间复杂度完成算法,

参考

Java:

public int maxProfit(int[] prices) {
    int sell = 0, prev_sell = 0, buy = Integer.MIN_VALUE, prev_buy;
    for (int price : prices) {
        prev_buy = buy;
        buy = Math.max(prev_sell - price, prev_buy);
        prev_sell = sell;
        sell = Math.max(prev_buy + price, prev_sell);
    }
    return sell;
}

Python:

def maxProfit(self, prices):
    if len(prices) < 2:
        return 0
    sell, buy, prev_sell, prev_buy = 0, -prices[0], 0, 0
    for price in prices:
        prev_buy = buy
        buy = max(prev_sell - price, prev_buy)
        prev_sell = sell
        sell = max(prev_buy + price, prev_sell)
    return sell

C++:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int buy = INT_MIN, pre_buy = 0, sell = 0, pre_sell = 0;
        for (int price : prices) {
            pre_buy = buy;
            buy = max(pre_sell - price, pre_buy);
            pre_sell = sell;
            sell = max(pre_buy + price, pre_sell);
        }
        return sell;
    }
};  

  

相似题目:

[LeetCode] 121. Best Time to Buy and Sell Stock 买卖股票的最佳时间

[LeetCode] 122. Best Time to Buy and Sell Stock II 买卖股票的最佳时间 II

[LeetCode] 123. Best Time to Buy and Sell Stock III 买卖股票的最佳时间 III

[LeetCode] 188. Best Time to Buy and Sell Stock IV 买卖股票的最佳时间 IV

 

All LeetCode Questions List 题目汇总

相关文章
相关标签/搜索