Stock Buy and Sell – Max 2 Transactions Allowed (original) (raw)

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) = 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.

Table of Content

[Naive Approach] Using Brute Force - O(n2) Time and O(1) Space

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.

C++ `

//Driver Code Starts #include #include using namespace std; //Driver Code Ends

// Function to find maximum profit // with one transaction starting from index idx int maxProfOne(vector &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;

}

// Function to find maximum profit // with at most two transactions int maxProfit(vector& prices) { int n = prices.size(); int minSoFar = prices[0], res = 0;

for (int i = 1; i < n; i++) {
    if (prices[i] > minSoFar) {
        
        // Profit from first transaction + best profit 
        // from remaining days
        int curr = prices[i] - minSoFar + maxProfOne(prices, i+1);
        res = max(res, curr);
    } 
    else {   
        minSoFar = min(minSoFar, prices[i]);
    }
}
return res;

}

//Driver Code Starts int main() { vector prices = { 10, 22, 5, 75, 65, 80 }; cout << maxProfit(prices); return 0; }

//Driver Code Ends

Java

//Driver Code Starts class GFG { //Driver Code Ends

// Function to find maximum profit 
// with one transaction starting from index idx
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;
}

// Function to find maximum profit 
// with at most two transactions
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) {
            
            // Profit from first transaction + best profit
            // from remaining days
            int curr = prices[i] - minSoFar + maxProfOne(prices, i+1);
            res = Math.max(res, curr);
        } else {
            minSoFar = Math.min(minSoFar, prices[i]);
        }
    }
    return res;
}

//Driver Code Starts public static void main(String[] args) { int[] prices = {10, 22, 5, 75, 65, 80}; System.out.println(maxProfit(prices)); } }

//Driver Code Ends

Python

Function to find maximum profit

with one transaction starting from index idx

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

Function to find maximum profit

with at most two transactions

def maxProfit(prices): n = len(prices) minSoFar = prices[0] res = 0

for i in range(1, n):
    if prices[i] > minSoFar:

        # Profit from first transaction + best profit 
        # from remaining days
        curr = prices[i] - minSoFar + maxProfOne(prices, i+1)
        res = max(res, curr)
    else:
        minSoFar = min(minSoFar, prices[i])
return res

#Driver Code Starts if name == "main": prices = [10, 22, 5, 75, 65, 80] print(maxProfit(prices))

#Driver Code Ends

C#

//Driver Code Starts using System;

class GFG { //Driver Code Ends

// Function to find maximum profit 
// with one transaction starting from index idx
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;
}

// Function to find maximum profit 
// with at most two transactions
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) {

            // Profit from first transaction + best profit 
            // from remaining days
            int curr = prices[i] - minSoFar + maxProfOne(prices, i+1);
            res = Math.Max(res, curr);
        } 
        else {
            minSoFar = Math.Min(minSoFar, prices[i]);
        }
    }
    return res;
}

//Driver Code Starts static void Main() { int[] prices = {10, 22, 5, 75, 65, 80}; Console.WriteLine(maxProfit(prices)); } }

//Driver Code Ends

JavaScript

// Function to find maximum profit // with one transaction starting from index idx 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;

}

// Function to find maximum profit // with at most two transactions function maxProfit(prices) { const n = prices.length; let minSoFar = prices[0], res = 0;

for (let i = 1; i < n; i++) {
    if (prices[i] > minSoFar) {

        // Profit from first transaction + best profit 
        // from remaining days
        let curr = prices[i] - minSoFar + maxProfOne(prices, i+1);
        res = Math.max(res, curr);
    } 
    else {
        minSoFar = Math.min(minSoFar, prices[i]);
    }
}
return res;

}

// Driver Code //Driver Code Starts const prices = [10, 22, 5, 75, 65, 80]; console.log(maxProfit(prices));

//Driver Code Ends

`

[Better Approach 1] Using Postfix Profit Array - O(n) Time and O(n) Space

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.

C++ `

//Driver Code Starts #include #include #include using namespace std; //Driver Code Ends

int maxProfit(vector& prices) { int n = prices.size(); if (n == 0) return 0;

vector<int> postfix(n, 0);
int maxPrice = prices[n - 1];

// Postfix array: max profit with 
// one transaction from day i to end
for (int i = n - 2; i >= 0; i--) {
    maxPrice = max(maxPrice, prices[i]);
    postfix[i] = max(postfix[i + 1], maxPrice - prices[i]);
}

int minPrice = prices[0], res = postfix[0];

// Combine prefix (first transaction)
// and postfix (second transaction)
for (int i = 1; i < n; i++) {
    minPrice = min(minPrice, prices[i]);
    int first = prices[i] - minPrice;
    res = max(res, first + postfix[i]);
}

return res;

}

//Driver Code Starts int main() { vector prices = {10, 22, 5, 75, 65, 80}; cout << maxProfit(prices); return 0; }

//Driver Code Ends

Java

//Driver Code Starts class GFG { //Driver Code Ends

static int maxProfit(int[] prices) {
    int n = prices.length;
    if (n == 0) return 0;
    
    int[] postfix = new int[n];
    int maxPrice = prices[n - 1];

    // Postfix array: max profit with 
    // one transaction from day i to end
    for (int i = n - 2; i >= 0; i--) {
        maxPrice = Math.max(maxPrice, prices[i]);
        postfix[i] = Math.max(postfix[i + 1], maxPrice - prices[i]);
    }

    int minPrice = prices[0], res = postfix[0];

    // Combine prefix (first transaction)
    // and postfix (second transaction)
    for (int i = 1; i < n; i++) {
        minPrice = Math.min(minPrice, prices[i]);
        int first = prices[i] - minPrice;
        res = Math.max(res, first + postfix[i]);
    }

    return res;
}

//Driver Code Starts public static void main(String[] args) { int[] prices = {10, 22, 5, 75, 65, 80}; System.out.println(maxProfit(prices)); } }

//Driver Code Ends

Python

def maxProfit(prices): n = len(prices) if n == 0: return 0

postfix = [0] * n
max_price = prices[-1]

# Postfix array: max profit with 
# one transaction from day i to end
for i in range(n - 2, -1, -1):
    max_price = max(max_price, prices[i])
    postfix[i] = max(postfix[i + 1], max_price - prices[i])

min_price = prices[0]
res = postfix[0]

# Combine prefix (first transaction)
# and postfix (second transaction)
for i in range(1, n):
    min_price = min(min_price, prices[i])
    first = prices[i] - min_price
    res = max(res, first + postfix[i])

return res

#Driver Code Starts if name == 'main': prices = [10, 22, 5, 75, 65, 80] print(maxProfit(prices))

#Driver Code Ends

C#

//Driver Code Starts using System; using System.Collections.Generic;

class GFG { //Driver Code Ends

static int maxProfit(int[] prices) {
    int n = prices.Length;
    if (n == 0) return 0;

    int[] postfix = new int[n];
    int maxPrice = prices[n - 1];

    // Postfix array: max profit with 
    // one transaction from day i to end
    for (int i = n - 2; i >= 0; i--) {
        maxPrice = Math.Max(maxPrice, prices[i]);
        postfix[i] = Math.Max(postfix[i + 1], maxPrice - prices[i]);
    }

    int minPrice = prices[0], res = postfix[0];

    // Combine prefix (first transaction)
    // and postfix (second transaction)
    for (int i = 1; i < n; i++) {
        minPrice = Math.Min(minPrice, prices[i]);
        int first = prices[i] - minPrice;
        res = Math.Max(res, first + postfix[i]);
    }

    return res;
}

//Driver Code Starts static void Main() { int[] prices = {10, 22, 5, 75, 65, 80}; Console.WriteLine(maxProfit(prices)); } }

//Driver Code Ends

JavaScript

function maxProfit(prices) { const n = prices.length; if (n === 0) return 0;

const postfix = new Array(n).fill(0);
let maxPrice = prices[n - 1];

// Postfix array: max profit with 
// one transaction from day i to end
for (let i = n - 2; i >= 0; i--) {
    maxPrice = Math.max(maxPrice, prices[i]);
    postfix[i] = Math.max(postfix[i + 1], maxPrice - prices[i]);
}

let minPrice = prices[0];
let res = postfix[0];

// Combine prefix (first transaction)
// and postfix (second transaction)
for (let i = 1; i < n; i++) {
    minPrice = Math.min(minPrice, prices[i]);
    const first = prices[i] - minPrice;
    res = Math.max(res, first + postfix[i]);
}

return res;

}

// Driver Code //Driver Code Starts const prices = [10, 22, 5, 75, 65, 80]; console.log(maxProfit(prices));

//Driver Code Ends

`

Idea: Exploring all possibilities

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 decisions while 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.

[Better Approach 2] Using Top Down Dp - O(n) Time and O(n) Space

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).

C++ `

//Driver Code Starts #include #include #include using namespace std; //Driver Code Ends

// Recursive helper function with memoization int maxProfitRec(int i, int k, int buy, vector &prices, vector<vector<vector>> &dp) {

// Base conditions
if (i == prices.size() || k == 0)
    return 0;

// If already computed
if (dp[i][k][buy] != -1)
    return dp[i][k][buy];

int profit = 0;

// If we can buy
if (buy == 1) {
    profit = max(-prices[i] + maxProfitRec(i + 1, k, 0, prices, dp),
                 maxProfitRec(i + 1, k, 1, prices, dp));
}

// If we can sell
else {
    profit = max(prices[i] + maxProfitRec(i + 1, k - 1, 1, prices, dp),
                 maxProfitRec(i + 1, k, 0, prices, dp));
}

return dp[i][k][buy] = profit;

}

// Find maximum profit with at most 2 transactions int maxProfit(vector &prices) { int n = prices.size();

// 3D memo table for states (index, transactions, buy/sell)
vector<vector<vector<int>>> dp(n, vector<vector<int>>(3, vector<int>(2, -1)));

return maxProfitRec(0, 2, 1, prices, dp);

}

//Driver Code Starts int main() { vector prices = {10, 22, 5, 75, 65, 80};

cout << maxProfit(prices);
return 0;

}

//Driver Code Ends

Java

//Driver Code Starts import java.util.Arrays;

class GFG { //Driver Code Ends

// Recursive helper function with memoization
static int maxProfitRec(int i, int k, int buy, int[] prices, int[][][] dp) {

    // Base case
    if (i == prices.length || k == 0)
        return 0;

    // If already computed
    if (dp[i][k][buy] != -1)
        return dp[i][k][buy];

    int profit;

    // If we can buy
    if (buy == 1)
        profit = Math.max(-prices[i] + maxProfitRec(i + 1, k, 0, prices, dp),
                          maxProfitRec(i + 1, k, 1, prices, dp));

    // If we can sell
    else
        profit = Math.max(prices[i] + maxProfitRec(i + 1, k - 1, 1, prices, dp),
                          maxProfitRec(i + 1, k, 0, prices, dp));

    return dp[i][k][buy] = profit;
}

// Find maximum profit with at most 2 transactions
static int maxProfit(int[] prices) {
    int n = prices.length;
    
    // 3D memo table for states (index, transactions, buy/sell)
    int[][][] dp = new int[n][3][2];
    for (int[][] arr : dp)
        for (int[] row : arr)
            Arrays.fill(row, -1);

    return maxProfitRec(0, 2, 1, prices, dp);
}

//Driver Code Starts public static void main(String[] args) { int[] prices = {10, 22, 5, 75, 65, 80}; System.out.println(maxProfit(prices)); } }

//Driver Code Ends

Python

Recursive helper function with memoization

def maxProfitRec(i, k, buy, prices, dp):

# Base case
if i == len(prices) or k == 0:
    return 0

# If already computed
if dp[i][k][buy] != -1:
    return dp[i][k][buy]

# If we can buy
if buy == 1:
    profit = max(-prices[i] + maxProfitRec(i + 1, k, 0, prices, dp),
                 maxProfitRec(i + 1, k, 1, prices, dp))
else:
    profit = max(prices[i] + maxProfitRec(i + 1, k - 1, 1, prices, dp),
                 maxProfitRec(i + 1, k, 0, prices, dp))

dp[i][k][buy] = profit
return profit

Find maximum profit with at most 2 transactions

def maxProfit(prices): n = len(prices)

# 3D memo table for states (index, transactions, buy/sell)
dp = [[[-1] * 2 for _ in range(3)] for _ in range(n)]
return maxProfitRec(0, 2, 1, prices, dp)

if name == "main": #Driver Code Starts prices = [10, 22, 5, 75, 65, 80] print(maxProfit(prices))

#Driver Code Ends

C#

//Driver Code Starts using System;

class GFG { //Driver Code Ends

// Recursive helper function with memoization
static int maxProfitRec(int i, int k, int buy, int[] prices, int[,,] dp) {

    // Base case
    if (i == prices.Length || k == 0)
        return 0;

    // If already computed
    if (dp[i, k, buy] != -1)
        return dp[i, k, buy];

    int profit;

    // If we can buy
    if (buy == 1)
        profit = Math.Max(-prices[i] + maxProfitRec(i + 1, k, 0, prices, dp),
                          maxProfitRec(i + 1, k, 1, prices, dp));

    // If we can sell
    else
        profit = Math.Max(prices[i] + maxProfitRec(i + 1, k - 1, 1, prices, dp),
                          maxProfitRec(i + 1, k, 0, prices, dp));

    return dp[i, k, buy] = profit;
}

// Find maximum profit with at most 2 transactions
static int maxProfit(int[] prices) {
    int n = prices.Length;
    
    // 3D memo table for states (index, transactions, buy/sell)
    int[,,] dp = new int[n, 3, 2];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < 3; j++)
            for (int b = 0; b < 2; b++)
                dp[i, j, b] = -1;

    return maxProfitRec(0, 2, 1, prices, dp);
}

//Driver Code Starts static void Main() { int[] prices = {10, 22, 5, 75, 65, 80}; Console.WriteLine(maxProfit(prices)); } }

//Driver Code Ends

JavaScript

// Recursive helper function with memoization function maxProfitRec(i, k, buy, prices, dp) {

// Base case
if (i === prices.length || k === 0)
    return 0;

// If already computed
if (dp[i][k][buy] !== -1)
    return dp[i][k][buy];

let profit;

// If we can buy
if (buy === 1)
    profit = Math.max(-prices[i] + maxProfitRec(i + 1, k, 0, prices, dp),
                      maxProfitRec(i + 1, k, 1, prices, dp));

// If we can sell
else
    profit = Math.max(prices[i] + maxProfitRec(i + 1, k - 1, 1, prices, dp),
                      maxProfitRec(i + 1, k, 0, prices, dp));

dp[i][k][buy] = profit;
return profit;

}

// Find maximum profit with at most 2 transactions function maxProfit(prices) { const n = prices.length;

// 3D memo table for states (index, transactions, buy/sell)
const dp = Array.from({ length: n }, () =>
    Array.from({ length: 3 }, () => Array(2).fill(-1))
);

return maxProfitRec(0, 2, 1, prices, dp);

}

// Driver Code //Driver Code Starts const prices = [10, 22, 5, 75, 65, 80]; console.log(maxProfit(prices));

//Driver Code Ends

`

[Expected Approach 1] Bottom Up Dp with Space Optimization - O(n) Time and O(1) Space

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.

C++ `

//Driver Code Starts #include #include #include using namespace std; //Driver Code Ends

int maxProfit(vector &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];

}

//Driver Code Starts int main() { vector price = { 10, 22, 5, 75, 65, 80 }; cout << maxProfit(price); return 0; }

//Driver Code Ends

Java

//Driver Code Starts class GFG { //Driver Code Ends

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];
}

//Driver Code Starts public static void main(String[] args) { int[] prices = {10, 22, 5, 75, 65, 80}; System.out.println(maxProfit(prices)); } }

//Driver Code Ends

Python

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": #Driver Code Starts prices = [10, 22, 5, 75, 65, 80] print(maxProfit(prices))

#Driver Code Ends

C#

//Driver Code Starts using System;

class GFG { //Driver Code Ends

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];
}

//Driver Code Starts static void Main(string[] args) { int[] prices = {10, 22, 5, 75, 65, 80}; Console.WriteLine(maxProfit(prices)); } }

//Driver Code Ends

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];

}

// Driver Code //Driver Code Starts let prices = [10, 22, 5, 75, 65, 80]; console.log(maxProfit(prices)); //Driver Code Ends

`

[Expected Approach 2] Further Space Optimization - O(n) Time and O(1) Space

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.

C++ `

//Driver Code Starts #include #include #include using namespace std; //Driver Code Ends

int maxProfit(vector &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;

}

//Driver Code Starts int main() { vector prices = { 10, 22, 5, 75, 65, 80 }; cout << maxProfit(prices); return 0; }

//Driver Code Ends

Java

//Driver Code Starts class GFG { //Driver Code Ends

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;
}

//Driver Code Starts public static void main(String[] args) { int[] prices = { 10, 22, 5, 75, 65, 80 }; System.out.println(maxProfit(prices)); } }

//Driver Code Ends

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": #Driver Code Starts prices = [10, 22, 5, 75, 65, 80] print(maxProfit(prices))

#Driver Code Ends

C#

//Driver Code Starts using System;

class GFG { //Driver Code Ends

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 
        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;
}

//Driver Code Starts static void Main() { int[] prices = { 10, 22, 5, 75, 65, 80 }; Console.WriteLine(maxProfit(prices)); } }

//Driver Code Ends

JavaScript

function maxProfit(prices) {

// 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 < 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;

}

//Driver Code Starts // Driver Code let prices = [10, 22, 5, 75, 65, 80]; console.log(maxProfit(prices));

//Driver Code Ends

`