Best Time to Buy and Sell Stock with Cooldown

Medium Dynamic Programming State Machine DP - Stock Problems Original on LeetCode

Best Time to Buy and Sell Stock with Cooldown is a medium dynamic programming problem solved with the state machine dp - stock problems pattern. The best approach, optimal (three-state machine), runs in O(n) time and O(1) space. Below are 2 approaches in Java, from memoised recursion up.

Problem

Unlimited transactions, but after you sell, you must wait one day (cooldown) before buying again. Return the maximum profit.

Examples

Example 1

Input
prices = [1, 2, 3, 0, 2]
Output
3
Why
buy, sell, cooldown, buy, sell.

Example 2

Input
prices = [1]
Output
0

Constraints

  • 1 <= prices.length <= 5000.
  • After selling you must wait one day before buying again.

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Memoised recursionO(n)O(n)
Optimal (three-state machine)O(n)O(1)

1Memoised recursion

TimeO(n)
SpaceO(n)

f(i, holding): if holding, sell (and jump to i + 2 because of the cooldown) or wait; if not, buy or wait.

  1. Selling moves to day i + 2.
Java
class Solution {
    private Integer[][] memo;

    public int maxProfit(int[] prices) {
        memo = new Integer[prices.length][2];
        return f(prices, 0, 0);
    }

    private int f(int[] p, int i, int holding) {
        if (i >= p.length) return 0;
        if (memo[i][holding] != null) return memo[i][holding];
        int wait = f(p, i + 1, holding);
        int act = holding == 1 ? p[i] + f(p, i + 2, 0) : -p[i] + f(p, i + 1, 1);
        return memo[i][holding] = Math.max(wait, act);
    }
}

2Optimal (three-state machine)

TimeO(n)
SpaceO(1)

hold = max(hold, rest - price) (buy only from rest); sold = hold + price; rest = max(rest, sold_yesterday). The answer is the better of sold and rest on the last day.

  1. hold = -prices[0], sold = 0, rest = 0.
  2. Each day compute the new values from yesterday's.
Java
class Solution {
    public int maxProfit(int[] prices) {
        int hold = -prices[0], sold = 0, rest = 0;
        for (int i = 1; i < prices.length; i++) {
            int prevSold = sold;
            sold = hold + prices[i];
            hold = Math.max(hold, rest - prices[i]);
            rest = Math.max(rest, prevSold);
        }
        return Math.max(sold, rest);
    }
}

Edge cases to test

  • Selling and buying on consecutive days is not allowed

Hints

Hint 1

Use three states: holding, just sold (cooling down), and resting (free to buy).

FAQ

What is the best time complexity for Best Time to Buy and Sell Stock with Cooldown?

Optimal (three-state machine) runs in O(n) time and O(1) extra space.

Which pattern does Best Time to Buy and Sell Stock with Cooldown use?

It is a dynamic programming problem that uses the state machine dp - stock problems pattern. Other problems with the same pattern: Best Time to Buy and Sell Stock, Best Time to Buy and Sell Stock II, Best Time to Buy and Sell Stock with Transaction Fee.

Is there a brute force solution for Best Time to Buy and Sell Stock with Cooldown?

Yes. Memoised recursion takes O(n) time and O(n) space. f(i, holding): if holding, sell (and jump to i + 2 because of the cooldown) or wait; if not, buy or wait.

Which edge cases should I test for Best Time to Buy and Sell Stock with Cooldown?

Selling and buying on consecutive days is not allowed.