Best Time to Buy and Sell Stock IV
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
0 ≤ k ≤ 5 - ◆
1 ≤ prices.length ≤ 10 - ◆
0 ≤ prices[i] ≤ 1000 - ◆
at most k 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
BruteGeneralize the single-transaction decision to a running counter of transactions still available: at every day, either skip it, or (if not holding) spend one of the remaining transaction slots to buy, or (if holding) spend nothing extra and sell to close out a slot. Recursing over both choices at every day covers every possible sequence of up to k transactions, but the same (day, holding, transactions-remaining) situation gets rediscovered on many different branches with no memory of earlier work.
O(2ⁿ)O(n)1class Solution {
2 private int[] prices;
3
4 public int maxProfit(int k, int[] prices) {
5 this.prices = prices;
6 return solve(0, false, k);
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 — k-Transaction State Arrays
OptimalStretch the four-variable pattern used for two transactions into a pair of arrays sized k+1: buy[t] is the best result after opening the t-th position, sell[t] the best result after closing it. Sweeping through the prices once, transaction slot 1 through k in order at every day, each buy[t] only ever needs sell[t-1] — the profit already banked from finishing the transaction before it — so by the time slot t is updated everything it depends on is already correct for that day.
O(n · k)O(k)1class Solution {
2 public int maxProfit(int k, int[] prices) {
3 int n = prices.length;
4 if (n == 0 || k == 0) return 0;
5 int[] buy = new int[k + 1];
6 int[] sell = new int[k + 1];
7 Arrays.fill(buy, Integer.MIN_VALUE);
8 for (int p : prices) {
9 for (int t = 1; t <= k; t++) {
10 buy[t] = Math.max(buy[t], sell[t - 1] - p);
11 sell[t] = Math.max(sell[t], buy[t] + p);
12 }
13 }
14 return sell[k];
15 }
16}