Best Time to Buy And Sell Stock With Cooldown

Best Time to Buy And Sell Stack With Cooldown

  • This problem is a variation of the classic “Buy and Sell Stock” challenge, incorporating a cooldown period after selling.
  • The goal is to maximize profit by strategically planning when to buy, sell, and stay idle.
N Queen problem for Chess

Best Time to Buy And Sell Stock With Cooldown Problem Description:

You are given an array prices where prices[i] represents the price of a stock on day ii. You may complete as many transactions as you’d like (buy one stock and sell one stock), but with the following restrictions:

  1. After selling a stock, you must wait for one day before buying again (cooldown period).
  2. You may only hold one stock at any given time.

Return the maximum profit achievable.

Example 1:

Example of N Queen problem

Explanation: Buy on day 0 (price = 1) and sell on day 1 (price = 3), profit = 3-1 = 2. Then buy on day 3 (price = 0) and sell on day 4 (price = 4), profit = 4-0 = 4. Total profit is 2 + 4 = 6.

Constraints:

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

Best Time to Buy And Sell Stock With Cooldown Solution

Recommendation for Time and Space Complexity – The solution should aim for O(n!) time and O(n²) space, where n is the size of the chessboard.

Hints for solving problems

There are mainly 4 approach to solve this problem-

  1. Recursion
  2. Dynamic Programming (Top-Down)
  3. Dynamic Programming (Bottom-up)
  4. Dynamic Programming (Space Optimized)

1. Recursion

  • Time complexity: O(n^2)
  • Space complexity: O(n)
class Solution {
public:
    int maxProfit(vector& prices) {
        return dfs(0, true, prices);
    }
    
private:
    int dfs(int i, bool buying, vector& prices) {
        if (i >= prices.size()) {
            return 0;
        }

        int cooldown = dfs(i + 1, buying, prices);
        if (buying) {
            int buy = dfs(i + 1, false, prices) - prices[i];
            return max(buy, cooldown);
        } else {
            int sell = dfs(i + 2, true, prices) + prices[i];
            return max(sell, cooldown);
        }
    }
};

2.Dynamic Programming (Top-Down)

    • Time complexityO(n)
    • Space complexityO(n)
class Solution {
public:
    unordered_map dp;
    
    int maxProfit(vector& prices) {
        return dfs(0, true, prices);
    }

private:
    int dfs(int i, bool buying, vector& prices) {
        if (i >= prices.size()) {
            return 0;
        }

        string key = to_string(i) + "-" + to_string(buying);
        if (dp.find(key) != dp.end()) {
            return dp[key];
        }

        int cooldown = dfs(i + 1, buying, prices);
        if (buying) {
            int buy = dfs(i + 1, false, prices) - prices[i];
            dp[key] = max(buy, cooldown);
        } else {
            int sell = dfs(i + 2, true, prices) + prices[i];
            dp[key] = max(sell, cooldown);
        }

        return dp[key];
    }
};

3. Dynamic Programming (Bottom-Up)

  • Time complexity: O(n)
  • Space complexity: O(n)
class Solution {
public:
    int maxProfit(vector& prices) {
        int n = prices.size();
        vector> dp(n + 1, vector(2, 0));  

        for (int i = n - 1; i >= 0; --i) {
            for (int buying = 1; buying >= 0; --buying) {
                if (buying == 1) {
                    int buy = dp[i + 1][0] - prices[i];
                    int cooldown = dp[i + 1][1];
                    dp[i][1] = max(buy, cooldown);
                } else {
                    int sell = (i + 2 < n) ? dp[i + 2][1] + prices[i] : prices[i];
                    int cooldown = dp[i + 1][0];
                    dp[i][0] = max(sell, cooldown);
                }
            }
        }

        return dp[0][1];
    }
};

4. Dynamic Programming (Space Optimized)

  • Time complexity: O(n)
  • Space complexity: O(1)
class Solution {
public:
    int col = 0, posDiag = 0, negDiag = 0;
    vector<string> board;
    vector<vector<string>> res;

    vector<vector<string>> solveNQueens(int n) {
        board.resize(n, string(n, '.'));
        
        backtrack(0, n);
        return res;
    }

    void backtrack(int r, int n) {
        if (r == n) {
            res.push_back(board);
            return;
        }
        for (int c = 0; c < n; c++) {
            if ((col & (1 << c)) || (posDiag & (1 << (r + c)))
                 || (negDiag & (1 << (r - c + n)))) {
                continue;
            }
            col ^= (1 << c);
            posDiag ^= (1 << (r + c));
            negDiag ^= (1 << (r - c + n));
            board[r][c] = 'Q';

            backtrack(r + 1, n);

            col ^= (1 << c);
            posDiag ^= (1 << (r + c));
            negDiag ^= (1 << (r - c + n));
            board[r][c] = '.';
        }
    }
};

More Articles