1. 程式人生 > >【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown

【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown

309. Best Time to Buy and Sell Stock with Cooldown

Description:

Say you have an array for which the i^{th} 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:

Input: [1,2,3,0,2]
Output: 3 
Explanation: transactions = [buy, sell, cooldown, buy, sell]

解題思路:

(1)動態規劃解法:

這道題可以用動態規劃思路來解決。這道題的難點在於如何寫出狀態轉移方程。下面我們來分析一下題目:

在每一次股票操作之後,都可能出現三種狀態:休息(rest)、持有(hold)和已賣出(sold)。下圖是這三種狀態的狀態機。

1)對於rest,有兩種情況:一種是,上一個時間再休息,現在接著休息。另一種是,上一個時間是賣出,那麼現在必須是休息狀態。

2)對於hold,有兩種情況:一種是,上一個時間是休息,現在可以買入股票,變成持有狀態。另一種是,上一個時間是持有,現在可以暫停交易進入休息,依然變成持有狀態。

3)對於sold,只能是把持有的股票賣出,變成已賣出狀態。

狀態機

 根據以上分析寫出,狀態轉移方程:

帶入例子中,驗證狀態轉移方程是否正確:

已經AC的程式碼:

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :type: int
        """
        if len(prices) <= 1:
            return  0
        hold = [0] * len(prices)
        sold = [0] * len(prices)
        rest = [0] * len(prices)
        hold[0] = -prices[0]
        sold[0] = -float("inf")
        for i in range(1,len(prices)):
            hold[i] = max(hold[i - 1], rest[i - 1] - prices[i])
            sold[i] = hold[i - 1] + prices[i]
            rest[i] = max(rest[i - 1], sold[i - 1])
        return max(sold[-1], rest[-1])

solution = Solution()
Input = [1, 2, 3, 0, 2]
print(solution.maxProfit(Input))

Reference:

【1】花花醬 LeetCode 309. Best Time to Buy and Sell Stock with Cooldown(視訊)

【2】【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown