Best Time to Buy and Sell Stock III
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ prices.length ≤ 10 - ◆
0 ≤ prices[i] ≤ 1000 - ◆
at most two buy-sell transactions are allowed; you must sell before buying again
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteAt every day there are exactly two choices depending on whether a share is currently held: buy or hold if not holding, sell or hold if holding. Trying both choices at every day and recursing covers every possible pair of transactions, but nothing is remembered between calls — the same (day, holding, transactions-remaining) situation gets explored over and over on different branches, so the work roughly doubles with every extra day.
O(2ⁿ)O(n)1class Solution {
2 private int[] prices;
3
4 public int maxProfit(int[] prices) {
5 this.prices = prices;
6 return solve(0, false, 2);
7 }
8
9 private int solve(int day, boolean holding, int txnsLeft) {
10 if (day == prices.length || txnsLeft == 0) return 0;
11 int doNothing = solve(day + 1, holding, txnsLeft);
12 int act;
13 if (holding) {
14 act = prices[day] + solve(day + 1, false, txnsLeft - 1);
15 } else {
16 act = -prices[day] + solve(day + 1, true, txnsLeft);
17 }
18 return Math.max(doNothing, act);
19 }
20}Optimal — Two-Transaction State Tracking
OptimalRather than branching on every day's decision, keep four running numbers that summarize the best result reachable so far under each of four situations: holding after the first buy, cash after the first sell, holding after the second buy (only reachable once a first sell already happened), and cash after the second sell. Each new day's price can only improve these four numbers, never make them worse, so a single left-to-right sweep updating all four in order settles the whole answer.
O(n)O(1)1class Solution {
2 public int maxProfit(int[] prices) {
3 int buy1 = Integer.MIN_VALUE, sell1 = 0, buy2 = Integer.MIN_VALUE, sell2 = 0;
4 for (int p : prices) {
5 buy1 = Math.max(buy1, -p);
6 sell1 = Math.max(sell1, buy1 + p);
7 buy2 = Math.max(buy2, sell1 - p);
8 sell2 = Math.max(sell2, buy2 + p);
9 }
10 return sell2;
11 }
12}