121. Best Time to Buy and Sell Stock - only 1 transaction allowed
int maxProfit(int[] prices) {
int profitWithoutStock = 0; // without => sell today if have it
int profitWithStock = Integer.MIN_VALUE; // with => either keep or buy today
for (int price: prices) {
profitWithStock = Math.max(
profitWithStock, // rest today ... profitWithStock on prev day
// profitWithoutStock-price // wrong cuz no "previous profit" to carry into buying cuz only 1 transaction allowed
-price // buy today - buying reduces treasury
);
// profitWithoutStock on current day either could be profitWithoutStock on prev day or....
profitWithoutStock = Math.max(
profitWithoutStock, // rest today
profitWithStock + price // sell today
);
}
return profitWithoutStock; // i.e profit on selling
}122. Best Time to Buy and Sell Stock II - infinite transactions => profit reuse allowed
Allowing same-day SELL → BUY means the cash from the sell is immediately reusable, even though buying and selling at the same price yields zero net profit
public int maxProfit(int[] prices) {
int profitWithoutStock = 0;
int profitWithStock = Integer.MIN_VALUE;
for (int price: prices) {
profitWithStock = Math.max(
profitWithStock,
profitWithoutStock - price // 121 forbids reusing profit for buying again; 122 allows it
);
profitWithoutStock = Math.max(
profitWithoutStock,
profitWithStock + price
);
}
return profitWithoutStock;
}123. Best Time to Buy and Sell Stock III - at most 2 transactions allowed
public int maxProfit(int[] prices) {
int k = 2;
int[] profitWithoutStock = new int[k + 1]; // profitWithoutStock[t] → best profit after t completed sells, and not holding stock
int[] profitWithStock = new int[k + 1];
Arrays.fill(profitWithStock, Integer.MIN_VALUE);
for (int price: prices) {
// When processing today’s price: must read from left (t-1) and must write to right (t). So fill right → left to avoid overwriting the source (just like Coin Change Combination (Single))
for (int t = k; t >= 1; t--) {
profitWithStock[t] = Math.max( // profitWithStock -> buying
profitWithStock[t],
profitWithoutStock[t - 1] - price // buying is start of a new transaction (t), so prev corresponds to the older transaction (t-1)
);
profitWithoutStock[t] = Math.max( // profitWithoutStock -> selling
profitWithoutStock[t],
profitWithStock[t] + price // selling is end of a transaction, so prev corresponds to the same transaction
);
}
}
return profitWithoutStock[k];
}188. Best Time to Buy and Sell Stock IV - at most k transactions allowed
public int maxProfit(int k, int[] prices) {
int[] profitWithoutStock = new int[k + 1];
int[] profitWithStock = new int[k + 1];
Arrays.fill(profitWithStock, Integer.MIN_VALUE);
for (int price: prices) {
for (int t = k; t >= 1; t--) {
profitWithStock[t] = Math.max(
profitWithStock[t],
profitWithoutStock[t - 1] - price
);
profitWithoutStock[t] = Math.max(
profitWithoutStock[t],
profitWithStock[t] + price
);
}
}
return profitWithoutStock[k];
}714. Best Time to Buy and Sell Stock with Transaction Fee
The transaction fee is only charged once for each stock purchase and sale
public int maxProfit(int[] prices, int fee) {
int profitWithoutStock = 0;
int profitWithStock = Integer.MIN_VALUE;
for (int price: prices) {
// Update the buy/hold state first so today's sell cannot fund today's buy (fee-sensitive)
profitWithStock = Math.max(
profitWithStock,
// profitWithoutStock - price - fee
profitWithoutStock - price
);
profitWithoutStock = Math.max(
profitWithoutStock,
// profitWithStock + price
profitWithStock + price - fee
);
}
return profitWithoutStock;
}309. Best Time to Buy and Sell Stock with Cooldown - 1 day cooldown
public int maxProfit(int[] prices) {
int profitWithoutStock = 0;
int profitWithStock = Integer.MIN_VALUE;
int profitWithoutStockTwoDaysAgo = 0;
for (int price: prices) {
int prevProfitWithoutStock = profitWithoutStock;
profitWithStock = Math.max(
profitWithStock,
profitWithoutStockTwoDaysAgo - price
);
profitWithoutStock = Math.max( // after this update prevProfitWithoutStock becomes profitWithoutStockTwoDaysAgo
profitWithoutStock,
profitWithStock + price
);
profitWithoutStockTwoDaysAgo = prevProfitWithoutStock;
}
return profitWithoutStock;
}Q. Best Time to Buy and Sell Stock with Cooldown - k day cooldown
public int maxProfit(int[] prices, int k) {
int profitWithoutStock = 0;
int profitWithStock = Integer.MIN_VALUE;
Deque < Integer > history = new ArrayDeque < > ();
// profitWithoutStock before day 0 is 0
for (int i = 0; i <= k; i++) { // Initialize sliding window of size (k + 1)
history.addLast(0);
}
for (int price: prices) {
history.pollFirst(); // since window size is fixed, so before adding in window have to remove first
history.addLast(profitWithoutStock); // before updating profitWithoutStock have to add it in history
int allowedBuyBase = history.peekFirst(); // above 2 lines shifted the window from [i-k-1, i-1] to [i-k, i]. So to get (i-k-1) need to peek again even after initial poll
profitWithStock = Math.max(
profitWithStock,
allowedBuyBase - price
);
profitWithoutStock = Math.max(
profitWithoutStock,
profitWithStock + price
);
}
return profitWithoutStock;
}