LeetCodee

309. Best Time to Buy and Sell Stock with Cooldown

Jump to Solution: Python Java C++ JavaScript C#

Problem Description

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)

Example 1:

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

Example 2:

Input: prices = [1]
Output: 0

Constraints:

  • 1 <= prices.length <= 5000
  • 0 <= prices[i] <= 1000

Solution

Python Solution

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        
        n = len(prices)
        # hold[i]: max profit if we hold stock at day i
        # sold[i]: max profit if we sold stock at day i
        # rest[i]: max profit if we rest at day i
        hold = [0] * n
        sold = [0] * n
        rest = [0] * n
        
        # Initialize first day
        hold[0] = -prices[0]  # Buy stock
        
        for i in range(1, n):
            # If we hold stock at day i, either we held it from day i-1,
            # or we buy it after resting on day i-1
            hold[i] = max(hold[i-1], rest[i-1] - prices[i])
            
            # If we sold stock at day i, we must have held it at day i-1
            sold[i] = hold[i-1] + prices[i]
            
            # If we rest at day i, we take the max profit from either
            # resting or selling at day i-1
            rest[i] = max(rest[i-1], sold[i-1])
        
        # Return the max of the last day's sold or rest state
        return max(sold[n-1], rest[n-1])

Time Complexity: O(n)

Where n is the length of the prices array.

Space Complexity: O(n)

For storing the dynamic programming arrays.

Java Solution

class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1) return 0;
        
        int n = prices.length;
        int[] hold = new int[n];
        int[] sold = new int[n];
        int[] rest = new int[n];
        
        // Initialize first day
        hold[0] = -prices[0];
        
        for (int i = 1; i < n; i++) {
            hold[i] = Math.max(hold[i-1], rest[i-1] - prices[i]);
            sold[i] = hold[i-1] + prices[i];
            rest[i] = Math.max(rest[i-1], sold[i-1]);
        }
        
        return Math.max(sold[n-1], rest[n-1]);
    }
}

Time Complexity: O(n)

Where n is the length of the prices array.

Space Complexity: O(n)

For storing the dynamic programming arrays.

C++ Solution

class Solution {
public:
    int maxProfit(vector& prices) {
        if (prices.empty()) return 0;
        
        int n = prices.size();
        vector hold(n, 0);
        vector sold(n, 0);
        vector rest(n, 0);
        
        // Initialize first day
        hold[0] = -prices[0];
        
        for (int i = 1; i < n; i++) {
            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[n-1], rest[n-1]);
    }
};

Time Complexity: O(n)

Where n is the length of the prices array.

Space Complexity: O(n)

For storing the dynamic programming arrays.

JavaScript Solution

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    if (!prices.length) return 0;
    
    const n = prices.length;
    const hold = new Array(n).fill(0);
    const sold = new Array(n).fill(0);
    const rest = new Array(n).fill(0);
    
    // Initialize first day
    hold[0] = -prices[0];
    
    for (let i = 1; i < n; i++) {
        hold[i] = Math.max(hold[i-1], rest[i-1] - prices[i]);
        sold[i] = hold[i-1] + prices[i];
        rest[i] = Math.max(rest[i-1], sold[i-1]);
    }
    
    return Math.max(sold[n-1], rest[n-1]);
};

Time Complexity: O(n)

Where n is the length of the prices array.

Space Complexity: O(n)

For storing the dynamic programming arrays.

C# Solution

public class Solution {
    public int MaxProfit(int[] prices) {
        if (prices == null || prices.Length <= 1) return 0;
        
        int n = prices.Length;
        int[] hold = new int[n];
        int[] sold = new int[n];
        int[] rest = new int[n];
        
        // Initialize first day
        hold[0] = -prices[0];
        
        for (int i = 1; i < n; i++) {
            hold[i] = Math.Max(hold[i-1], rest[i-1] - prices[i]);
            sold[i] = hold[i-1] + prices[i];
            rest[i] = Math.Max(rest[i-1], sold[i-1]);
        }
        
        return Math.Max(sold[n-1], rest[n-1]);
    }
}

Time Complexity: O(n)

Where n is the length of the prices array.

Space Complexity: O(n)

For storing the dynamic programming arrays.

Approach Explanation

The solution uses dynamic programming with state machine approach:

  1. Key Insight:
    • Three possible states: hold, sold, rest
    • State transitions with cooldown
    • Maximum profit tracking
    • Optimal substructure
  2. Algorithm Steps:
    • Initialize state arrays
    • Define state transitions
    • Handle cooldown period
    • Track maximum profit

Example walkthrough:

  • prices = [1,2,3,0,2]
  • Track states for each day
  • Consider cooldown after selling
  • Find optimal sequence

Optimization insights:

  • Space optimization possible
  • State compression
  • Early termination
  • Pattern recognition

Edge Cases:

  • Empty price array
  • Single price
  • Decreasing prices
  • Alternating prices