Last Updated: April 2, 2026
This is the third problem in the "Best Time to Buy and Sell Stock" series, and it introduces a specific constraint: at most two transactions. In Stock I, you could make one transaction. In Stock II, you had unlimited transactions. Here, you are capped at two.
Why does limiting it to two make things harder? Because now you need to decide where to "split" your effort. Should you use both transactions, or is one enough? If you use both, how do you pick two non-overlapping buy-sell windows that maximize the combined profit? You cannot just find the single best transaction and then find the second best in the remaining days, because the two transactions might interact. For example, one large profit might span a range where two smaller but better-combined profits exist.
The key observation is that any two non-overlapping transactions divide the array into a "left transaction" (days 0 to some split point) and a "right transaction" (from that split point onward). This partitioning idea, combined with the fact that we can precompute the best single transaction from the left and right, leads to an elegant O(n) solution.
1 <= prices.length <= 10^5 --> With n up to 100,000, we need O(n log n) or better. An O(n^2) approach would hit 10^10 operations, which is far too slow.0 <= prices[i] <= 10^5 --> Prices are non-negative. The maximum possible profit from a single transaction is 10^5, so two transactions can yield at most 2 * 10^5, fitting comfortably in a 32-bit integer.The most straightforward way to think about two transactions is: any valid pair of transactions can be separated by a split point. The first transaction happens entirely within days 0 to i, and the second happens entirely within days i to n-1 (they can share the boundary day since selling and buying on the same day is a no-op).
So if we could quickly answer "what is the best single transaction in days 0..i?" and "what is the best single transaction in days i..n-1?", we could try every split point and pick the maximum sum. Finding the best single transaction in a subarray is the classic Stock I problem: track the minimum price seen so far and the maximum profit. But doing this from scratch for every split point would be O(n) per split, giving O(n^2) total.
For each split point, we recompute the best single transaction on each side from scratch. But the left subarray only grows by one element as we move the split point. What if we precomputed the best left and right profits so that evaluating each split becomes O(1)?
The brute force recomputes the best single transaction for every split point. But notice that "best single transaction in days 0..i" is just the Stock I problem solved incrementally. As we scan left to right, we track the minimum price so far and the best profit so far. We can store the answer for every prefix in an array leftProfit[i] in a single O(n) pass.
Similarly, the "best single transaction in days i..n-1" can be computed by scanning right to left, tracking the maximum price so far, stored in rightProfit[i].
Once we have both arrays, the answer is simply max(leftProfit[i] + rightProfit[i]) for all i.
Any pair of non-overlapping transactions must have some dividing point in the array. The first transaction completes on or before day i, and the second transaction starts on or after day i. By precomputing the best single transaction for every prefix and every suffix, we can evaluate every possible split in O(1), bringing the total to O(n).
This "prefix/suffix decomposition" technique shows up in many problems. Whenever you need to combine the best result from the left side with the best result from the right side, precomputing prefix and suffix arrays is a powerful strategy.
leftProfit of size n. Scan left to right, tracking the minimum price seen so far. At each day i, leftProfit[i] = max profit from a single transaction in days 0..i.rightProfit of size n. Scan right to left, tracking the maximum price seen so far. At each day i, rightProfit[i] = max profit from a single transaction in days i..n-1.leftProfit[i] + rightProfit[i]. Return the maximum.The O(n) time is already optimal, but we are using O(n) extra space. Can we track all possible stages of the two transactions simultaneously using only a constant number of variables?
Instead of splitting the array, think about the states you can be in as you process each day: before any transaction, after first buy, after first sell, after second buy, after second sell. At each day, you can either stay in your current state or move to the next one. We track the best profit achievable in each state using four variables.
The elegant part: buy1 tracks the minimum cost of the first buy. sell1 tracks the best profit after completing the first transaction. buy2 builds on sell1, effectively using the first transaction's profit as a "discount" for the second buy. And sell2 tracks the final answer.
The four variables form a pipeline where each state builds on the previous one. buy1 finds the cheapest day to buy the first stock. sell1 finds the most profitable day to sell it. buy2 takes the profit from sell1 and uses it as a "budget" for buying the second stock. And sell2 finds the best day to close out the second transaction.
We update all four variables on the same day, which seems like it might allow buying and selling on the same day. But that is perfectly fine. If we buy and sell on the same day, the profit is zero, so it is equivalent to not making that transaction. The algorithm naturally handles the case where one transaction is better than two.
buy1 = -infinity, sell1 = 0, buy2 = -infinity, sell2 = 0.buy1 = max(buy1, -price): Buy at the lowest price so far.sell1 = max(sell1, buy1 + price): Sell the first stock for maximum profit.buy2 = max(buy2, sell1 - price): Buy the second stock, using first transaction's profit.sell2 = max(sell2, buy2 + price): Sell the second stock for maximum total profit.sell2.