Best Time to Buy and Sell Stock with Transaction Fee
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ prices.length ≤ 10 - ◆
0 ≤ prices[i] ≤ 1000 - ◆
0 ≤ fee ≤ 100
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursion Without Memoization
BruteAt every day there are only ever two live options: stay exactly as you are, or act on today's price — buy if nothing is held, sell (and pay the fee right there) if something is. Recursing through both choices at every day and keeping the better result is correct, but "staying as you are" and "acting" both lead back into the same solve(day, holding) shape from countless different histories, so the same day-and-position combination gets fully re-solved over and over as the array grows.
O(2ⁿ)O(n)1class Solution {
2 private int[] prices;
3 private int fee;
4 public int maxProfit(int[] prices, int fee) {
5 this.prices = prices;
6 this.fee = fee;
7 return solve(0, false);
8 }
9 private int solve(int day, boolean holding) {
10 if (day == prices.length) return 0;
11 int doNothing = solve(day + 1, holding);
12 int act;
13 if (holding) {
14 act = prices[day] - fee + solve(day + 1, false);
15 } else {
16 act = -prices[day] + solve(day + 1, true);
17 }
18 return Math.max(doNothing, act);
19 }
20}Optimal — Bottom-Up 2-State DP
OptimalOnly two numbers ever matter as the days go by: the best total with nothing currently held (`cash`), and the best total assuming a share is currently held (`hold`, already down the price it cost to buy). Each new day can only improve one state from the other's *previous* value — cash improves if selling today (collecting the price and paying the fee) beats holding on, and hold improves if buying today beats whatever position was already held. Carrying just these two running numbers forward, one day at a time, replaces the exponential branching with a single linear pass.
O(n)O(1)1class Solution {
2 public int maxProfit(int[] prices, int fee) {
3 int n = prices.length;
4 if (n == 0) return 0;
5 int cash = 0, hold = -prices[0];
6 for (int i = 1; i < n; i++) {
7 int prevCash = cash;
8 cash = Math.max(cash, hold + prices[i] - fee);
9 hold = Math.max(hold, prevCash - prices[i]);
10 }
11 return cash;
12 }
13}