![]() |
VOOZH | about |
Given an array prices[], where prices[i] represents the price of a stock on the i-th day, find the maximum profit that can be earned by performing at most two transactions.
Each transaction consists of one buy and one sell operation, and a new transaction can begin only after the previous one is completed (i.e., you cannot hold more than one stock at a time).
Examples:
Input: prices[] = [10, 22, 5, 75, 65, 80]
Output: 87
Explanation:
Buy at 10, sell at 22, profit = 22 - 10 = 12
Buy at 5 and sell at 80, total profit = 12 + (80 - 5) = 87Input: prices[] = [100, 30, 15, 10, 8, 25, 80]
Output: 72
Explanation: Only one transaction needed here. Buy at price 8 and sell at 80.Input: prices[] = [90, 80, 70, 60, 50]
Output: 0
Explanation: Not possible to earn.
Table of Content
We can use the concept of maximum profit from one transaction to solve this for two transactions. For each day i, we assume the first transaction ends on or before i, and the second transaction starts after i.
By combining these two profits for every possible split point i, we get the maximum achievable profit from at most two transactions.
87
We can optimize above approach by using a postfix array to store future profits.
First, we calculate profit2[i], which represents the maximum profit achievable from one transaction starting at day i. This is done by traversing from right to left, keeping track of the maximum price so far and updating -
profit2[i] = max(profit2[i + 1], maxPrice - prices[i])
Then, we traverse from left to right to calculate the maximum total profit by combining:
This avoids recalculating profits repeatedly using the idea of prefix (first transaction) and postfix (second transaction) profits.
87
At any given day, we can be in one of two states - ready to buy or ready to sell. So,
The idea is to explore all possible buy and sell decisionswhile ensuring that at most two transactions are allowed.
Suppose, maxProfitRec(i, k, buy) returns the maximum profit from day i onward, with k transactions left and the option to either buy (buy = 1) or sell (buy = 0).
From each state, we have two choices:
If we are allowed to buy (buy = 1):
profit = max(-prices[i] + maxProfitRec(i+1, k, 0), maxProfitRec(i+1, k, 1))If we must sell (buy = 0):
profit = max(prices[i] + maxProfitRec(i+1, k-1, 1), maxProfitRec(i+1, k, 0))
The recursion stops when all days are processed or no transactions are left.
To avoid repeated calculations while exploring all possibilities, we can use memoization, where the result of each state (i, k, buy) is stored and reused whenever the same state is encountered again, thus eliminating overlapping subproblems and improving efficiency.
Create a 3D DP table where dp[i][k][buy] stores the maximum profit achievable starting from day i, with k transactions remaining, and the current state being either ready to buy (buy = 1) or ready to sell (buy = 0).
87
From the memoized state transitions, we can observe that,
Since the current day’s result depends only on the next day’s states, we do not need to store the full 3D DP table.
We maintain two 2D arrays — curr and next, where dp[k][b] represents:
We iterate backward from the last day to the first and fill these states:
After computing for day i, we copy curr to next to move one step backward. Finally, curr[2][1] gives the maximum profit starting from day 0 with 2 transactions allowed.
87
This approach optimizes the previous DP solution by observing that at any given point, the maximum profit depends only on a few previous states, not the entire DP table.
So instead of maintaining a 2D array, we track four essential states using variables:
We iterate through each day’s price and update these states in sequence:
firstBuy = max(firstBuy, -price)
choose between keeping the previous buy or buying today’s stock
firstSell = max(firstSell, firstBuy + price)
choose between keeping the previous sell or selling today’s stock
secondBuy = max(secondBuy, firstSell - price)
choose between keeping the previous second buy or buying today after the first sell
secondSell = max(secondSell, secondBuy + price)
choose between keeping the previous second sell or selling today
Each step builds upon the previous one — simulating two complete transactions in constant space. Finally, secondSell holds the maximum achievable profit after at most two transactions.
87