👨‍💻
LeetCode
  • Overview
  • Mixed / Design
    • Two Sum (4 Qs)
      • 0001. Two Sum
      • 0167. Two Sum II - Input array is sorted
      • 0170. Two Sum III - Data structure design
      • 0653. Two Sum IV - Input is a BST
    • 0015. 3Sum
    • 0208. Implement Trie (Prefix Tree)
  • String
    • 0014. Longest Common Prefix
    • 0028. Implement strStr()
    • 0344. Reverse String
    • 0151. Reverse Words in a String
    • 0557. Reverse Words in a String III
    • 0067. Add Binary
    • 0415. Add Strings
    • 0038. Count and Say
    • 0394. Decode String
    • 0953. Verifying an Alien Dictionary
    • 0020. Valid Parentheses
  • Linked List
    • 0002. Add Two Numbers
    • 0445. Add Two Numbers II
    • 0021. Merge Two Sorted Lists
    • 0023. Merge k Sorted Lists
    • 0206. Reverse Linked List
    • 0019. Remove Nth Node From End of List
  • Tree
    • 0098. Validate BST
    • 0100. Same Tree
    • 0101. Symmetric Tree
    • 0226. Invert Binary Tree
    • 0110. Balanced Binary Tree
    • 0250. Count Univalue Subtrees
    • 0654. Maximum Binary Tree
    • Binary Tree Traversal (7 Qs)
      • 0144. Preorder Traversal
      • 0145. Postorder Traversal
      • 0094. Inorder Traversal
      • 0102. Level Order Traversal
      • 0104. Maximum Depth
      • 0111. Minimum Depth
      • 1302. Deepest Leaves Sum
      • 0993. Cousins in Binary Tree
    • N-ary Tree Traversal (4 Qs)
      • 0589. Preorder Traversal
      • 0590. Postorder Traversal
      • 0429. Level Order Traversal
      • 0559. Maximum Depth
    • Convert to BST (2 Qs)
      • 0108. Convert Sorted Array to Binary Search Tree
      • 0109. Convert Sorted List to Binary Search Tree
  • Binary Search
    • 0704. Binary Search
    • 0035. Search Insert Position
    • 0278. First Bad Version
    • 0367. Valid Perfect Square
    • 0069. Sqrt(x)
    • 0875. Koko Eating Bananas
    • 1011. Capacity To Ship Packages Within D Days
    • 0410. Split Array Largest Sum
    • 0004. Median of Two Sorted Arrays
  • Two Pointer
    • 0075. Sort Colors
    • 0088. Merge Sorted Array
    • 0283. Move Zeroes
    • 0125. Valid Palindrome
    • 0011. Container With Most Water
    • 0026. Remove Duplicates from Sorted Array
  • Sliding Window
    • 0003. Longest Substring Without Repeating Characters
  • Sorting
    • 0148. Sort List
    • 0912. Sort an Array
    • 0215. Kth Largest in Array
  • Dynamic Programming
    • 0509. Fibonacci Number
    • 1137. N-th Tribonacci Number
    • 0055. Jump Game
    • 0053. Maximum Subarray
    • 0022. Generate Parentheses
    • 0005. Longest Palindromic Substring
    • 0072. Edit Distance
    • Buy and Sell Stock (6 Qs)
      • 0122. Best Time to Buy and Sell Stock II
      • 0714. Best Time to Buy and Sell Stock with Transaction Fee
      • 0121. Best Time to Buy and Sell Stock
      • 0309. Best Time to Buy and Sell Stock with Cooldown
      • 0123. Best Time to Buy and Sell Stock III
      • 0188. Best Time to Buy and Sell Stock IV
  • DFS / BFS
    • 0200. Number of Islands
  • Math
    • 0007. Reverse Integer
    • 0009. Palindrome Number
Powered by GitBook
On this page

Was this helpful?

  1. Dynamic Programming
  2. Buy and Sell Stock (6 Qs)

0309. Best Time to Buy and Sell Stock with Cooldown

Medium | Array + DP | 32 ms (96.27%), 14.6 MB (38.63%)

Previous0121. Best Time to Buy and Sell StockNext0123. Best Time to Buy and Sell Stock III

Last updated 3 years ago

Was this helpful?

Source: GitHub:

You are given an array prices where prices[i] is the price of a given stock on the ith day.

Find the maximum profit you can achieve. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times) with the following restrictions:

  • After you sell your stock, you cannot buy stock on the next day (i.e., cooldown one day).

Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).

Constraints:

  • 1 <= prices.length <= 5000

  • 0 <= prices[i] <= 1000

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

Input: prices = [1]
Output: 0

We can use Final State Machine to solve the series of these problems.

Note that this problem limits us to have one day cooldown after selling a stock (belongs to no-hold state), so for calculating of the hold state's profit, we need the other variable to record the profit whenever we sell a stock.

This variable could be initialized as 0 (to simulate as we buy and sell stock in the same day long time ago). Then, this variable is updated by previous no-hold state's profit to create a one-day gap.

  • Hold state means you hold the stock.

    • Since you don't have any stocks at the beginning, the profit at this state is initialized with negative infinity.

    • The profit in this state is calculated by: previous no-hold state's profit - current stock price (= buy) = previous profit when we sell stock - current stock price

  • No-Hold state means you do not hold any stocks.

    • Since you don't have any stocks at the beginning (you're initially at this state ), the profit at this state is initialized with 0.

    • The profit in this state is calculated by: previous hold state's profit + current stock price (= sell)

    • Return the profit at the no-hold state as the maximum profit since the hold state still has stock on hold.

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        #  (base case)
        if len(prices) == 0 or len(prices) == 1: return 0
        
        # ==================================================
        #  Array + Dynamic Programming              (FSM)  =
        # ==================================================
        # time  : O(n)
        # space : O(1)

        hold, noHold = float('-inf'), 0
        
        #  after selling stock, you cannot buy stock on the next day = NO HOLD state
        preDaySell = 0
        
        for price in prices:
            preHold, preNoHold = hold, noHold
            
            #  due to cooldown, cannot use preNoHold's profit to buy stock, use preDaySell
            hold   = max(preHold,   preDaySell - price)
            noHold = max(preNoHold, preHold    + price)
            
            #  record at the end to have an one-day gap (still 0 after 1st iteration)
            preDaySell = preNoHold
            
        return noHold
class Solution {
    /**
     * @time  : O(n)
     * @space : O(1)
     */
     
    public int maxProfit(int[] prices) {
        /* base case */
        if(prices.length == 1) return 0;
        
        int hold = Integer.MIN_VALUE, noHold = 0;
        int preDaySell = 0;
        
        for(int price: prices) {
            int preHold = hold, preNoHold = noHold;
            
            hold   = Math.max(preHold,   preDaySell - price);
            noHold = Math.max(preNoHold, preHold    + price );
            
            preDaySell = preNoHold;
        }
        
        return noHold;
    }
}
LeetCode - Best Time to Buy and Sell Stock with Cooldown
Solution / Performance