Stock Buy and Sell – Max 2 Transactions Allowed
Last Updated :
23 Jul, 2025
In the stock market, a person buys a stock and sells it on some future date. Given the stock prices of n days in an array prices[ ]. Find out the maximum profit a person can make in at most 2 transactions. A transaction is equivalent to (buying + selling) of a stock and a new transaction can start only when the previous transaction has been completed.
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) = 87
Input: 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.
[Naive Approach] - O(n^2) Time and O(1) Space
We strongly recommend you to refer Stock Buy and Sell with At-Most one Transaction. We mainly use the idea of the one transaction efficient solution here.
Step-by-step approach:
- Traverse the prices[] from left to right and keep track of the minimum price seen so far in a variable minSoFar.
- If the current price is more than minSoFar, we keep this transaction as first transaction and call the one-transaction-solution for the subarray after the current index to find the profit for second transaction.
- Else, we update the minSoFar.
- At the end, we return maximum of all values obtained in step 2.
C++
#include <bits/stdc++.h>
using namespace std;
int maxProfOne(vector<int> &prices, int idx) {
int minSoFar = prices[idx], res = 0;
for (int i = idx+1; i < prices.size(); i++) {
minSoFar = min(minSoFar, prices[i]);
res = max(res, prices[i] - minSoFar);
}
return res;
}
// Maxmum profit with two transactions allwoed
int maxProfit(vector<int>& prices) {
int n = prices.size();
int minSoFar = prices[0], res = 0;
for (int i = 1; i < n; i++) {
if (prices[i] > minSoFar) {
int curr = prices[i] - minSoFar +
maxProfOne(prices, i);
res = max(res, curr);
} else {
minSoFar = min(minSoFar, prices[i]);
}
}
return res;
}
int main() {
vector<int> prices = { 10, 22, 5, 75, 65, 80 };
cout << maxProfit(prices);
return 0;
}
Java
import java.util.*;
class GfG {
// Maxmum profit with one transaction allwoed
static int maxProfOne(int[] prices, int idx)
{
int minSoFar = prices[idx], res = 0;
for (int i = idx + 1; i < prices.length; i++) {
minSoFar = Math.min(minSoFar, prices[i]);
res = Math.max(res, prices[i] - minSoFar);
}
return res;
}
// Maxmum profit with two transactions allwoed
static int maxProfit(int[] prices)
{
int n = prices.length;
int minSoFar = prices[0], res = 0;
for (int i = 1; i < n; i++) {
if (prices[i] > minSoFar) {
int curr = prices[i] - minSoFar
+ maxProfOne(prices, i);
res = Math.max(res, curr);
}
else {
minSoFar = Math.min(minSoFar, prices[i]);
}
}
return res;
}
public static void main(String[] args)
{
int[] prices = { 10, 22, 5, 75, 65, 80 };
System.out.println(maxProfit(prices));
}
}
Python
# Python program to implement Stock Buy
# and Sell – Max 2 Transactions Allowed
# Maxmum profit with one transaction allwoed
def maxProfOne(prices, idx):
minSoFar = prices[idx]
res = 0
for i in range(idx+1, len(prices)):
minSoFar = min(minSoFar, prices[i])
res = max(res, prices[i] - minSoFar)
return res
# Maxmum profit with two transactions allwoed
def maxProfit(prices):
n = len(prices)
minSoFar = prices[0]
res = 0
for i in range(1, n):
if prices[i] > minSoFar:
curr = prices[i] - minSoFar + maxProfOne(prices, i)
res = max(res, curr)
else:
minSoFar = min(minSoFar, prices[i])
return res
if __name__ == "__main__":
prices = [10, 22, 5, 75, 65, 80]
print(maxProfit(prices))
C#
// C# program to implement Stock Buy
// and Sell – Max 2 Transactions Allowed
using System;
class GfG {
// Maxmum profit with one transaction allwoed
static int maxProfOne(int[] prices, int idx)
{
int minSoFar = prices[idx], res = 0;
for (int i = idx + 1; i < prices.Length; i++) {
minSoFar = Math.Min(minSoFar, prices[i]);
res = Math.Max(res, prices[i] - minSoFar);
}
return res;
}
// Maxmum profit with two transactions allwoed
static int maxProfit(int[] prices)
{
int n = prices.Length;
int minSoFar = prices[0], res = 0;
for (int i = 1; i < n; i++) {
if (prices[i] > minSoFar) {
int curr = prices[i] - minSoFar
+ maxProfOne(prices, i);
res = Math.Max(res, curr);
}
else {
minSoFar = Math.Min(minSoFar, prices[i]);
}
}
return res;
}
static void Main()
{
int[] prices = { 10, 22, 5, 75, 65, 80 };
Console.WriteLine(maxProfit(prices));
}
}
JavaScript
// JavaScript program to implement Stock Buy
// and Sell – Max 2 Transactions Allowed
// Maxmum profit with one transaction allwoed
function maxProfOne(prices, idx)
{
let minSoFar = prices[idx], res = 0;
for (let i = idx + 1; i < prices.length; i++) {
minSoFar = Math.min(minSoFar, prices[i]);
res = Math.max(res, prices[i] - minSoFar);
}
return res;
}
// Maxmum profit with two transactions allwoed
function maxProfit(prices)
{
let n = prices.length;
let minSoFar = prices[0], res = 0;
for (let i = 1; i < n; i++) {
if (prices[i] > minSoFar) {
let curr = prices[i] - minSoFar
+ maxProfOne(prices, i);
res = Math.max(res, curr);
}
else {
minSoFar = Math.min(minSoFar, prices[i]);
}
}
return res;
}
let prices = [ 10, 22, 5, 75, 65, 80 ];
console.log(maxProfit(prices));
[Better Approach] - Using Postfix Profit Array - O(n) Time and O(n) Space
The idea is to split the problem into two parts: find the best single transaction up to each point from the end, then find the best pair of transactions by combining the best profit from the first transaction and the best profit from the second transaction.
Step by step approach:
- First, traverse the prices array from right to left to find the maximum profit for a single transaction ending at each position.
- Store these maximum profits in an array where profit[i] represents the maximum profit possible from a single transaction if buying at or after position i.
- Next, traverse the array from left to right to find the minimum price seen so far at each position.
- For each position, calculate the total profit by adding the profit from a single transaction before the current position and the profit from a single transaction after the current position.
- Keep track of the maximum combined profit and return it as the final result.
C++
#include <bits/stdc++.h>
using namespace std;
int maxProfit(vector<int>& prices) {
int n = prices.size();
// Create profit vector and initialize it as 0
vector<int> profit(n, 0);
int maxPrice = prices[n - 1];
for (int i = n - 2; i >= 0; i--) {
// maxPrice has maximum of price[i..n-1]
maxPrice = max(maxPrice, prices[i]);
// Update profit[i]
profit[i] = max(profit[i + 1], maxPrice - prices[i]);
}
// Variable to store the maximum
// profit using two transactions
int res = 0;
int minPrice = prices[0];
for (int i = 1; i < n; i++) {
// minPrice is the minimum price in price[0..i]
minPrice = min(minPrice, prices[i]);
// Calculate the maximum profit by adding
// the profit of the first transaction
res = max(res, profit[i] + (prices[i] - minPrice));
}
return res;
}
int main() {
vector<int> prices = { 10, 22, 5, 75, 65, 80 };
cout << maxProfit(prices);
return 0;
}
Java
class GfG {
static int maxProfit(int[] prices) {
int n = prices.length;
// Create profit array and initialize it as 0
int[] profit = new int[n];
int maxPrice = prices[n - 1];
for (int i = n - 2; i >= 0; i--) {
maxPrice = Math.max(maxPrice, prices[i]);
profit[i] = Math.max(profit[i + 1], maxPrice - prices[i]);
}
int res = 0;
int minPrice = prices[0];
for (int i = 1; i < n; i++) {
// minPrices is the minimum prices in prices[0..i]
minPrice = Math.min(minPrice, prices[i]);
res = Math.max(res, profit[i] + (prices[i] - minPrice));
}
return res;
}
public static void main(String[] args) {
int[] prices = { 10, 22, 5, 75, 65, 80 };
System.out.println(maxProfit(prices));
}
}
Python
def maxProfit(prices):
n = len(prices)
# Create profit array and initialize it as 0
profit = [0] * n
maxPrice = prices[-1]
for i in range(n - 2, -1, -1):
# maxPrice has maximum of price[i..n-1]
maxPrice = max(maxPrice, prices[i])
# Update profit[i]
profit[i] = max(profit[i + 1], maxPrice - prices[i])
# Variable to store the maximum
# profit using two transactions
res = 0
minPrice = prices[0]
for i in range(1, n):
# minPrice is the minimum price in price[0..i]
minPrice = min(minPrice, prices[i])
# Calculate the maximum profit by adding
# the profit of the first transaction
res = max(res, profit[i] + (prices[i] - minPrice))
return res
if __name__ == "__main__":
prices = [10, 22, 5, 75, 65, 80]
print(maxProfit(prices))
C#
using System;
class GfG {
static int maxProfit(int[] prices) {
int n = prices.Length;
// Create profit array and initialize it as 0
int[] profit = new int[n];
int maxPrice = prices[n - 1];
for (int i = n - 2; i >= 0; i--) {
// maxPrice has maximum of price[i..n-1]
maxPrice = Math.Max(maxPrice, prices[i]);
// Update profit[i]
profit[i] = Math.Max(profit[i + 1], maxPrice - prices[i]);
}
int res = 0;
int minPrice = prices[0];
for (int i = 1; i < n; i++) {
// minPrice is the minimum price in price[0..i]
minPrice = Math.Min(minPrice, prices[i]);
// Calculate the maximum profit by adding
// the profit of the first transaction
res = Math.Max(res, profit[i] + (prices[i] - minPrice));
}
return res;
}
static void Main() {
int[] prices = { 10, 22, 5, 75, 65, 80 };
Console.WriteLine(maxProfit(prices));
}
}
JavaScript
function maxProfit(prices) {
let n = prices.length;
// Create profit array and initialize it as 0
let profit = new Array(n).fill(0);
let maxPrice = prices[n - 1];
for (let i = n - 2; i >= 0; i--) {
// maxPrice has maximum of price[i..n-1]
maxPrice = Math.max(maxPrice, prices[i]);
// Update profit[i]
profit[i] = Math.max(profit[i + 1], maxPrice - prices[i]);
}
let res = 0;
let minPrice = prices[0];
for (let i = 1; i < n; i++) {
// minPrice is the minimum price in price[0..i]
minPrice = Math.min(minPrice, prices[i]);
// Calculate the maximum profit by adding
// the profit of the first transaction
res = Math.max(res, profit[i] + (prices[i] - minPrice));
}
return res;
}
let prices = [10, 22, 5, 75, 65, 80];
console.log(maxProfit(prices));
[Expected Approach 1] - Using Dynamic Programming - O(n) Time and O(1) Space
The solution is based on Stock Buy and Sell – At-most k Transactions Allowed.
The idea is to use dynamic programming with state variables representing the current day, number of transactions remaining, and buy/sell state to find the maximum profit possible from at most 2 transactions.
Step by step approach:
- Create two 2D arrays where dp[k][j] represents the maximum profit with k transactions remaining and j indicating buy/sell state.
- Process the prices array from the last day to the first day, calculating maximum profit for each state.
- For each day and transaction count, choose the better option between making a transaction or skipping it.
- After processing each day, move current state to next state for the next iteration.
- The final answer is curr[2][1], representing the maximum profit starting from day 0 with 2 transactions.
C++
#include <bits/stdc++.h>
using namespace std;
// Function to return max profit from at most 2
// transation
int maxProfit(vector<int> &prices){
int n = prices.size();
if (n == 0)
return 0;
vector<vector<int>> curr(3, vector<int>(2, 0));
vector<vector<int>> next(3, vector<int>(2, 0));
// Iterate from the last day to the first
for (int i = n - 1; i >= 0; i--){
for (int k = 1; k <= 2; k++){
// Calculate for buy state
curr[k][1] = max(-prices[i] +
next[k][0], next[k][1]);
// Calculate for sell state
curr[k][0] = max(prices[i] +
next[k - 1][1], next[k][0]);
}
// Move current state to next, for the
// next iteration
next = curr;
}
return curr[2][1];
}
int main() {
vector<int> price = { 10, 22, 5, 75, 65, 80 };
cout << maxProfit(price);
return 0;
}
Java
class GfG {
static int maxProfit(int[] prices) {
int n = prices.length;
if (n == 0)
return 0;
int[][] curr = new int[3][2];
int[][] next = new int[3][2];
// Iterate from the last day to the first
for (int i = n - 1; i >= 0; i--) {
for (int k = 1; k <= 2; k++) {
// Calculate for buy state
curr[k][1] = Math.max(-prices[i] + next[k][0], next[k][1]);
// Calculate for sell state
curr[k][0] = Math.max(prices[i] + next[k - 1][1], next[k][0]);
}
// Move current state to next, for the
// next iteration
next = curr.clone();
}
return curr[2][1];
}
public static void main(String[] args) {
int[] prices = {10, 22, 5, 75, 65, 80};
System.out.println(maxProfit(prices));
}
}
Python
# Function to return max profit from at most 2
# transaction
def maxProfit(prices):
n = len(prices)
if n == 0:
return 0
curr = [[0] * 2 for _ in range(3)]
next = [[0] * 2 for _ in range(3)]
# Iterate from the last day to the first
for i in range(n - 1, -1, -1):
for k in range(1, 3):
# Calculate for buy state
curr[k][1] = max(-prices[i] + next[k][0], next[k][1])
# Calculate for sell state
curr[k][0] = max(prices[i] + next[k - 1][1], next[k][0])
# Move current state to next, for the
# next iteration
next = [row[:] for row in curr]
return curr[2][1]
if __name__ == "__main__":
prices = [10, 22, 5, 75, 65, 80]
print(maxProfit(prices))
C#
using System;
class GfG {
// Function to return max profit from at most 2
// transaction
static int maxProfit(int[] prices) {
int n = prices.Length;
if (n == 0)
return 0;
int[,] curr = new int[3, 2];
int[,] next = new int[3, 2];
// Iterate from the last day to the first
for (int i = n - 1; i >= 0; i--) {
for (int k = 1; k <= 2; k++) {
// Calculate for buy state
curr[k, 1] = Math.Max(-prices[i] + next[k, 0], next[k, 1]);
// Calculate for sell state
curr[k, 0] = Math.Max(prices[i] + next[k - 1, 1], next[k, 0]);
}
// Move current state to next, for the
// next iteration
Array.Copy(curr, next, curr.Length);
}
return curr[2, 1];
}
static void Main(string[] args) {
int[] prices = {10, 22, 5, 75, 65, 80};
Console.WriteLine(maxProfit(prices));
}
}
JavaScript
function maxProfit(prices) {
let n = prices.length;
if (n === 0)
return 0;
let curr = Array.from({ length: 3 }, () => [0, 0]);
let next = Array.from({ length: 3 }, () => [0, 0]);
// Iterate from the last day to the first
for (let i = n - 1; i >= 0; i--) {
for (let k = 1; k <= 2; k++) {
// Calculate for buy state
curr[k][1] = Math.max(-prices[i] + next[k][0], next[k][1]);
// Calculate for sell state
curr[k][0] = Math.max(prices[i] + next[k - 1][1], next[k][0]);
}
// Move current state to next, for the
// next iteration
next = curr.map(row => [...row]);
}
return curr[2][1];
}
let prices = [10, 22, 5, 75, 65, 80];
console.log(maxProfit(prices));
[Expected Approach 2] - Using State Machine - O(n) Time and O(1) Space
This solution is mainly a simplified version of the above DP solution. Instead of creating arrays, we use 4 variables.
The idea is to initialize four variables for taking care of the firstBuy, firstSell, secondBuy, secondSell. Set first buy and second buy as INT_MIN and first and second sell as 0. This is to ensure to get profit from transactions. Iterate through the array and return the second sell as it will store maximum profit.
- If we choose to rest, we remain in same state
- If we buy/sell, we spend/earn some money (price of the stock on that day) and go to next state.
C++
#include <bits/stdc++.h>
using namespace std;
// Function to return max profit from at most 2
// transation
int maxProfit(vector<int> prices) {
// Variables to store the maximum profit
// after the first and second transactions
int firstBuy = INT_MIN;
int firstSell = 0;
int secondBuy = INT_MIN;
int secondSell = 0;
// Iterate over each day's stock prices
for (int i = 0; i < prices.size(); i++) {
firstBuy = max(firstBuy, -prices[i]);
firstSell = max(firstSell, firstBuy + prices[i]);
secondBuy = max(secondBuy, firstSell - prices[i]);
secondSell = max(secondSell, secondBuy + prices[i]);
}
// The result is the maximum
// profit after the second sell
return secondSell;
}
int main() {
vector<int> prices = { 10, 22, 5, 75, 65, 80 };
cout << maxProfit(prices);
return 0;
}
Java
class GfG {
// Function to return max profit from at most 2
// transation
static int maxProfit(int[] prices) {
// Variables to store the maximum profit
// after the first and second transactions
int firstBuy = Integer.MIN_VALUE;
int firstSell = 0;
int secondBuy = Integer.MIN_VALUE;
int secondSell = 0;
// Iterate over each day's stock prices
for (int i = 0; i < prices.length; i++) {
// Calculate maximum profit
firstBuy = Math.max(firstBuy, -prices[i]);
firstSell = Math.max(firstSell, firstBuy + prices[i]);
secondBuy = Math.max(secondBuy, firstSell - prices[i]);
secondSell = Math.max(secondSell, secondBuy + prices[i]);
}
// The result is the maximum
// profit after the second sell
return secondSell;
}
public static void main(String[] args) {
int[] prices = { 10, 22, 5, 75, 65, 80 };
System.out.println(maxProfit(prices));
}
}
Python
def maxProfit(prices):
# Variables to store the maximum profit
# after the first and second transactions
firstBuy = float('-inf')
firstSell = 0
secondBuy = float('-inf')
secondSell = 0
# Iterate over each day's stock prices
for i in range(len(prices)):
# Calculate maximum profit
firstBuy = max(firstBuy, -prices[i])
firstSell = max(firstSell, firstBuy + prices[i])
secondBuy = max(secondBuy, firstSell - prices[i])
secondSell = max(secondSell, secondBuy + prices[i])
# The result is the maximum
# profit after the second sell
return secondSell
if __name__ == "__main__":
prices = [10, 22, 5, 75, 65, 80]
print(maxProfit(prices))
C#
using System;
class GfG {
// Function to return max profit from at most 2
// transation
static int maxProfit(int[] prices) {
// Variables to store the maximum profit
// after the first and second transactions
int firstBuy = int.MinValue;
int firstSell = 0;
int secondBuy = int.MinValue;
int secondSell = 0;
// Iterate over each day's stock prices
for (int i = 0; i < prices.Length; i++) {
// Calculate maximum profit
firstSell = Math.Max(firstSell, firstBuy + prices[i]);
secondBuy = Math.Max(secondBuy, firstSell - prices[i]);
secondSell = Math.Max(secondSell, secondBuy + prices[i]);
}
// The result is the maximum
// profit after the second sell
return secondSell;
}
static void Main() {
int[] prices = { 10, 22, 5, 75, 65, 80 };
Console.WriteLine(maxProfit(prices));
}
}
JavaScript
// Function to return max profit from at most 2
// transation
function maxProfit(price) {
// Variables to store the maximum profit
// after the first and second transactions
let firstBuy = -Infinity;
let firstSell = 0;
let secondBuy = -Infinity;
let secondSell = 0;
// Iterate over each day's stock price
for (let i = 0; i < price.length; i++) {
// Calculate maximum profit
firstBuy = Math.max(firstBuy, -price[i]);
firstSell = Math.max(firstSell, firstBuy + price[i]);
secondBuy = Math.max(secondBuy, firstSell - price[i]);
secondSell = Math.max(secondSell, secondBuy + price[i]);
}
// The result is the maximum
// profit after the second sell
return secondSell;
}
let price = [10, 22, 5, 75, 65, 80];
console.log(maxProfit(price));
Buy and Sell a Share at most twice | DSA Problem
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem