Best Time to Buy and Sell Stock with Cooldown medium
Problem Statement
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 (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).
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
Steps and Explanation
This problem can be solved using dynamic programming. We'll maintain three arrays:
buy[i]
: The maximum profit you can achieve on dayi
if you buy a stock on that day.sell[i]
: The maximum profit you can achieve on dayi
if you sell a stock on that day.rest[i]
: The maximum profit you can achieve on dayi
if you are in a cooldown state (neither buying nor selling).
The base cases are:
buy[0] = -prices[0]
(buying on day 0)sell[0] = 0
(can't sell on day 0 without buying first)rest[0] = 0
(no profit on day 0)
The recursive relations are:
buy[i] = max(buy[i-1], rest[i-1] - prices[i])
(Either keep the previous buy state, or transition from rest state by buying)sell[i] = max(sell[i-1], buy[i-1] + prices[i])
(Either keep the previous sell state, or transition from buy state by selling)rest[i] = max(rest[i-1], sell[i-1])
(Either keep previous rest state, or transition from sell state to cool down)
Finally, the maximum profit will be max(sell[n-1], rest[n-1])
where n
is the length of prices
. We use rest[n-1]
because we could end in a cooldown state with the maximum profit.
Code (Java)
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int n = prices.length;
int[] buy = new int[n];
int[] sell = new int[n];
int[] rest = new int[n];
buy[0] = -prices[0];
sell[0] = 0;
rest[0] = 0;
for (int i = 1; i < n; i++) {
buy[i] = Math.max(buy[i - 1], rest[i - 1] - prices[i]);
sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);
rest[i] = Math.max(rest[i - 1], sell[i - 1]);
}
return Math.max(sell[n - 1], rest[n - 1]);
}
}
Complexity Analysis
- Time Complexity: O(n), where n is the length of the
prices
array. We iterate through the array once. - Space Complexity: O(n), due to the
buy
,sell
, andrest
arrays. This can be optimized to O(1) by only storing the previous day's values instead of the entire arrays. This optimization is shown below.
Optimized Code (Java) with O(1) Space
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length <= 1) {
return 0;
}
int buy = -prices[0];
int sell = 0;
int rest = 0;
for (int i = 1; i < prices.length; i++) {
int prevBuy = buy;
int prevSell = sell;
int prevRest = rest;
buy = Math.max(prevBuy, prevRest - prices[i]);
sell = Math.max(prevSell, prevBuy + prices[i]);
rest = Math.max(prevRest, prevSell);
}
return Math.max(sell, rest);
}
}
This optimized version achieves the same result with significantly reduced space complexity.