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.
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 iii. You may complete as many transactions as you’d like (buy one stock and sell one stock), but with the following restrictions:
- After selling a stock, you must wait for one day before buying again (cooldown period).
- You may only hold one stock at any given time.
Return the maximum profit achievable.
Example 1:
Example 1
Input: prices = [1,3,4,0,4]
Output: 6
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.
Example 2
Input: prices = [1]
Output: 0
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-
- Recursion
- Dynamic Programming (Top-Down)
- Dynamic Programming (Bottom-up)
- Dynamic Programming (Space Optimized)
1. Recursion
- Time complexity: O(n^2)
- Space complexity: O(n)
C++
Java
Python
JavaScript
C++
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); } } };
Java
public class Solution { public int maxProfit(int[] prices) { return dfs(0, true, prices); } private int dfs(int i, boolean buying, int[] prices) { if (i >= prices.length) { return 0; } int cooldown = dfs(i + 1, buying, prices); if (buying) { int buy = dfs(i + 1, false, prices) - prices[i]; return Math.max(buy, cooldown); } else { int sell = dfs(i + 2, true, prices) + prices[i]; return Math.max(sell, cooldown); } } }
Python
class Solution: def maxProfit(self, prices: List[int]) -> int: def dfs(i, buying): if i >= len(prices): return 0 cooldown = dfs(i + 1, buying) if buying: buy = dfs(i + 1, not buying) - prices[i] return max(buy, cooldown) else: sell = dfs(i + 2, not buying) + prices[i] return max(sell, cooldown) return dfs(0, True)
JavaScript
class Solution { /** * @param {number[]} prices * @return {number} */ maxProfit(prices) { const dfs = (i, buying) => { if (i >= prices.length) { return 0; } let cooldown = dfs(i + 1, buying); if (buying) { let buy = dfs(i + 1, false) - prices[i]; return Math.max(buy, cooldown); } else { let sell = dfs(i + 2, true) + prices[i]; return Math.max(sell, cooldown); } } return dfs(0, true); } }
2.Dynamic Programming (Top-Down)
- Time complexity: O(n)
- Space complexity: O(n)
C++
Java
Python
JavaScript
C++
class Solution { public: unordered_mapdp; 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]; } };
Java
public class Solution { private Mapdp = new HashMap<>(); public int maxProfit(int[] prices) { return dfs(0, true, prices); } private int dfs(int i, boolean buying, int[] prices) { if (i >= prices.length) { return 0; } String key = i + "-" + buying; if (dp.containsKey(key)) { return dp.get(key); } int cooldown = dfs(i + 1, buying, prices); if (buying) { int buy = dfs(i + 1, false, prices) - prices[i]; dp.put(key, Math.max(buy, cooldown)); } else { int sell = dfs(i + 2, true, prices) + prices[i]; dp.put(key, Math.max(sell, cooldown)); } return dp.get(key); } }
Python
class Solution: def maxProfit(self, prices: List[int]) -> int: dp = {} # key=(i, buying) val=max_profit def dfs(i, buying): if i >= len(prices): return 0 if (i, buying) in dp: return dp[(i, buying)] cooldown = dfs(i + 1, buying) if buying: buy = dfs(i + 1, not buying) - prices[i] dp[(i, buying)] = max(buy, cooldown) else: sell = dfs(i + 2, not buying) + prices[i] dp[(i, buying)] = max(sell, cooldown) return dp[(i, buying)] return dfs(0, True)
JavaScript
class Solution { /** * @param {number[]} prices * @return {number} */ maxProfit(prices) { const dp = {}; const dfs = (i, buying) => { if (i >= prices.length) { return 0; } let key = `${i}-${buying}`; if (key in dp) { return dp[key]; } let cooldown = dfs(i + 1, buying); if (buying) { let buy = dfs(i + 1, false) - prices[i]; dp[key] = Math.max(buy, cooldown); } else { let sell = dfs(i + 2, true) + prices[i]; dp[key] = Math.max(sell, cooldown); } return dp[key]; } return dfs(0, true); } }
3. Dynamic Programming (Bottom-Up)
- Time complexity: O(n)
- Space complexity: O(n)
C++
Java
Python
JavaScript
C++
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]; } };
Java
public class Solution { public int maxProfit(int[] prices) { int n = prices.length; int[][] dp = new int[n + 1][2]; 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] = Math.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] = Math.max(sell, cooldown); } } } return dp[0][1]; } }
Python
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]; } };
JavaScript
class Solution { /** * @param {number[]} prices * @return {number} */ maxProfit(prices) { const n = prices.length; const dp = Array.from({ length: n + 1 }, () => [0, 0]); for (let i = n - 1; i >= 0; i--) { for (let buying = 1; buying >= 0; buying--) { if (buying === 1) { let buy = dp[i + 1][0] - prices[i]; let cooldown = dp[i + 1][1]; dp[i][1] = Math.max(buy, cooldown); } else { let sell = (i + 2 < n) ? dp[i + 2][1] + prices[i] : prices[i]; let cooldown = dp[i + 1][0]; dp[i][0] = Math.max(sell, cooldown); } } } return dp[0][1]; } }
4. Dynamic Programming (Space Optimized)
- Time complexity: O(n)
- Space complexity: O(1)
C++
Java
Python
JavaScript
C++
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] = '.'; } } };
Java
public class Solution { public int maxProfit(int[] prices) { int n = prices.length; int dp1_buy = 0, dp1_sell = 0; int dp2_buy = 0; for (int i = n - 1; i >= 0; i--) { int dp_buy = Math.max(dp1_sell - prices[i], dp1_buy); int dp_sell = Math.max(dp2_buy + prices[i], dp1_sell); dp2_buy = dp1_buy; dp1_buy = dp_buy; dp1_sell = dp_sell; } return dp1_buy; } }
Python
class Solution: def maxProfit(self, prices: List[int]) -> int: n = len(prices) dp1_buy, dp1_sell = 0, 0 dp2_buy = 0 for i in range(n - 1, -1, -1): dp_buy = max(dp1_sell - prices[i], dp1_buy) dp_sell = max(dp2_buy + prices[i], dp1_sell) dp2_buy = dp1_buy dp1_buy, dp1_sell = dp_buy, dp_sell return dp1_buy
JavaScript
class Solution { /** * @param {number[]} prices * @return {number} */ maxProfit(prices) { const n = prices.length; let dp1_buy = 0, dp1_sell = 0; let dp2_buy = 0; for (let i = n - 1; i >= 0; i--) { let dp_buy = Math.max(dp1_sell - prices[i], dp1_buy); let dp_sell = Math.max(dp2_buy + prices[i], dp1_sell); dp2_buy = dp1_buy; dp1_buy = dp_buy; dp1_sell = dp_sell; } return dp1_buy; } }