Open In App

Stock Buy and Sell - At-most k Transactions Allowed

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In share trading, a buyer buys shares and sells on a future date. Given the stock price of n days, the trader is allowed to make at most k transactions (a transaction is a combination of a buy and a sell), where a new transaction can only start after the previous transaction is complete, find out the maximum profit that a share trader could have made. 

Examples:

Input: prices = [10, 22, 5, 80], k = 2
Output: 87
Explanation: Buy on 1st day at 10 and sell on 2nd day at 22. Then, again buy on 3rd day at 5 and sell on 4th day at 80. Total profit = 12 + 75 = 87

Input: prices = [12, 14, 17, 10, 14, 13, 12, 15], k = 3
Output: 12
Explanation: Buy on 1st day and at 12 and sell on 3rd day at 17. Then, again buy on 4th day at 10 and sell on 5th day at 14. Lastly, buy on 7th day at 12 and sell on 8th day at 15. Total profit = 5 + 4 + 3 = 12

Input: prices = [100, 30, 15, 10, 8, 25, 80], k = 3
Output: 72
Explanation: Buy on 5th day at 8 and sell on 7th day at 80. Total profit = 72.

Input: prices = [90, 80, 70, 60, 50], k = 1
Output: 0
Explanation: Not possible to earn.

There are multiple variations of this problem. If only one buy and sell transaction is allowed, we can use the maximum difference between two elements approach. For at most two transactions, we can either follow the approach discussed here or use the given methods specifically for k=2. If unlimited transactions are permitted, we can adopt the strategy outlined here.

To solve this problem, we need to analyze the possible decisions we can make on each day. Given a day i, we have three choices:

  1. Buy a stock (if we haven't already bought one).
  2. Sell a stock (if we previously bought one).
  3. Do nothing and move to the next day without buying or selling.

The complexity of the problem arises because, for each day i, we must track both the number of remaining transactions and the state of our previous trade (whether we have bought or sold). To efficiently represent this, we define three states:

  • i → The current day (index in the prices array).
  • k → The number of transactions remaining.
  • buy → A flag indicating whether we are in a buying state (1) or a selling state (0).

Recurrence Relation:

  • If we can buy on day i: profit(i, k, 1) = profit(i + 1, k, 0) - prices[i]
  • If we can sell on day i: profit(i, k, 0) = profit(i + 1, k - 1, 1) + prices[i]
  • If we do nothing: profit(i, k, buy) = profit(i + 1, k, buy)

Return 0 if no transactions are left (k <= 0) or all days are processed (i >= n), otherwise return the maximum profit from the three cases.

C++
#include <bits/stdc++.h>
using namespace std;

// Utility function to calculate maximum profit
int maxProfitUtil(int i, int k, int buy,
                  vector<int> &prices){

    // Base case: if no transactions left
    // or end of price list is reached
    if (k <= 0 || i >= prices.size())
        return 0;

    int result = 0, profit = 0;

    // If we are in a 'buy' state
    if (buy){
      
        // Calculate profit by either buying
        // at current price or skipping
        profit = maxProfitUtil(i + 1, k, 0, prices)
          - prices[i];
        result = max(result, profit);
    }
    else{
      
        // If in a 'sell' state, calculate profit
        // by selling at current price
        profit = prices[i] + 
          maxProfitUtil(i + 1, k - 1, 1,  prices);
        result = max(result, profit);
    }

    // Consider the option to skip the current
    // price
    profit = maxProfitUtil(i + 1, k, buy, prices);
    return result = max(result, profit);
}

// Function to return max profit from k
// transation
int maxProfit(vector<int> &prices, int k){
  
    // Start from first price, in 'buy' state
    return maxProfitUtil(0, k, 1, prices);
}

int main(){
    int k = 2;
    vector<int> prices = {10, 22, 5, 80};
    cout << maxProfit(prices, k) << endl;

    return 0;
}
Java
import java.util.*;

class GfG {
    // Utility function to calculate max profit
    static int maxProfitUtil(int i, int k,
                         int buy,int[] prices){

        // Base case: no transactions or end of list
        if (k <= 0 || i >= prices.length)
            return 0;

        int result = 0, profit = 0;

        // If we are in a 'buy' state
        if (buy == 1){
          
            // Buy at current price or skip
            profit = maxProfitUtil(i + 1, k, 0,
                           prices) - prices[i];
            result = Math.max(result, profit);
        } else{
          
            // Sell at current price or skip
            profit = prices[i] + 
              maxProfitUtil(i + 1,k - 1,1,prices);
            result = Math.max(result, profit);
        }

        // Skip current price
        profit = maxProfitUtil(i + 1, k, buy,
                               prices);
        return Math.max(result, profit);
    }

    // Function to return max profit with k
    // transactions
    static int maxProfit(int[] prices, int k){
      
        // Start from first price in 'buy' state
        return maxProfitUtil(0, k, 1, prices);
    }

    public static void main(String[] args){
        int k = 2;
        int[] prices = {10, 22, 5, 80};

        System.out.println(maxProfit(prices, k));
    }
}
Python
# Utility function to calculate max profit
def maxProfitUtil(i, k, buy, prices):

    # Base case: no transactions or end of list
    if k <= 0 or i >= len(prices):
        return 0

    result = 0
    profit = 0

    # If we are in a 'buy' state
    if buy:
      
        # Buy at current price or skip
        profit = maxProfitUtil(i + 1, k, 0, 
                               prices) - prices[i]
        result = max(result, profit)
    else:
      
        # Sell at current price or skip
        profit = prices[i] + maxProfitUtil(i + 1,
                                  k - 1,1, prices)
        result = max(result, profit)

    # Skip current price
    profit = maxProfitUtil(i + 1, k, buy, prices)
    return max(result, profit)

# Function to return max profit with k transactions
def maxProfit(prices, k):
  
    # Start from first price in 'buy' state
    return maxProfitUtil(0, k, 1, prices)

if __name__ == "__main__":
    k = 2
    prices = [10, 22, 5, 80]
    print(maxProfit(prices, k))
C#
using System;

class GfG {
    // Utility function to calculate max profit
    static int MaxProfitUtil(int i, int k, int buy,
                             int[] prices){

        // Base case: no transactions or end of list
        if (k <= 0 || i >= prices.Length)
            return 0;

        int result = 0, profit = 0;

        // If we are in a 'buy' state
        if (buy == 1) {

            // Buy at current price or skip
            profit = MaxProfitUtil(i + 1, k, 0, prices)
                                         - prices[i];
            result = Math.Max(result, profit);
        }
        else {

            // Sell at current price or skip
            profit = prices[i] + MaxProfitUtil(i + 1,
                                   k - 1, 1, prices);
            result = Math.Max(result, profit);
        }

        // Skip current price
        profit = MaxProfitUtil(i + 1, k, buy, prices);
        return Math.Max(result, profit);
    }

    // Function to return max profit with k
    // transactions
    static int maxProfit(int[] prices, int k){
        return MaxProfitUtil(0, k, 1, prices);
    }

    static void Main(){
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };

        Console.WriteLine(maxProfit(prices, k));
    }
}
JavaScript
// Utility function to calculate max profit
function maxProfitUtil(i, k, buy, prices){
    // Base case: no transactions or end of list
    if (k <= 0 || i >= prices.length)
        return 0;

    let result = 0, profit = 0;

    // If we are in a 'buy' state
    if (buy) {
    
        // Buy at current price or skip
        profit = maxProfitUtil(i + 1, k, 0, prices)
                 - prices[i];
        result = Math.max(result, profit);
    }
    else {
    
        // Sell at current price or skip
        profit = prices[i]
                 + maxProfitUtil(i + 1, k - 1, 1, prices);
        result = Math.max(result, profit);
    }

    // Skip current price
    profit = maxProfitUtil(i + 1, k, buy, prices);
    return Math.max(result, profit);
}

// Function to return max profit with k transactions
function maxProfit(prices, k){
    return maxProfitUtil(0, k, 1, prices);
}

const k = 2;
const prices = [ 10, 22, 5, 80 ];
console.log(maxProfit(prices, k));

Output
87

Time Complexity: O(2n), exponential time
Auxiliary Space: O(n), due to recursion stack

[Better Approach-1] Using Memoization - O(n*k) time and O(n*k) space

The above approach involves multiple overlapping subproblems, leading to redundant computations. To optimize this, we can use memoization, which stores previously computed results and avoids recalculating them.

To achieve this, we maintain a 3D memoization array (memo) where:

  • memo[i][k][buy] stores the maximum profit achievable starting from day i, with k transactions remaining, and the current state (buy or sell).

By storing results for each unique combination of (i, k, buy), we ensure that once a state is computed, it doesn't need to be recalculated, significantly improving efficiency.

C++
#include <bits/stdc++.h>
using namespace std;

// Utility function to calculate maximum profit
int maxProfitUtil(int i, int k, int buy, vector<vector<vector<int>>> &memo, vector<int> &prices)
{

    // Base case: if no transactions left
    // or end of price list is reached
    if (k <= 0 || i >= prices.size())
        return 0;

    if (memo[i][k][buy] != -1)
        return memo[i][k][buy];

    int result = 0, profit = 0;

    // If we are in a 'buy' state
    if (buy)
    {

        // Calculate profit by either buying
        // at current price or skipping
        profit = maxProfitUtil(i + 1, k, 0, memo, prices) - prices[i];
        result = max(result, profit);
    }
    else
    {

        // If in a 'sell' state, calculate profit
        // by selling at current price
        profit = prices[i] + maxProfitUtil(i + 1, k - 1, 1, memo, prices);
        result = max(result, profit);
    }

    // Consider the option to skip the current
    // price
    profit = maxProfitUtil(i + 1, k, buy, memo, prices);
    result = max(result, profit);
    return memo[i][k][buy] = result;
}

// Function to return max profit from k
// transation
int maxProfit(vector<int> &prices, int k)
{
    int n = prices.size();

    // Initilize 3D vector for memoization
    vector<vector<vector<int>>> memo(n + 1, vector<vector<int>>(k + 1, vector<int>(3, -1)));

    // Start from first price, in 'buy' state
    return maxProfitUtil(0, k, 1, memo, prices);
}

int main()
{
    int k = 2;
    vector<int> prices = {10, 22, 5, 80};
    cout << maxProfit(prices, k) << endl;

    return 0;
}
Java
import java.util.Arrays;

class GfG {

    // Utility function to calculate max profit
    static int maxProfitUtil(int i, int k, int buy,
                             int[][][] memo, int[] prices)
    {

        // Base case: no transactions or end of list
        if (k <= 0 || i >= prices.length)
            return 0;

        if (memo[i][k][buy] != -1)
            return memo[i][k][buy];

        int result = 0, profit = 0;

        // If we are in a 'buy' state
        if (buy == 1) {

            // Buy at current price or skip
            profit
                = maxProfitUtil(i + 1, k, 0, memo, prices)
                  - prices[i];
            result = Math.max(result, profit);
        }
        else {

            // Sell at current price
            profit = prices[i]
                     + maxProfitUtil(i + 1, k - 1, 1, memo,
                                     prices);
            result = Math.max(result, profit);
        }

        // Skip current price
        profit = maxProfitUtil(i + 1, k, buy, memo, prices);
        result = Math.max(result, profit);

        memo[i][k][buy] = result;
        return result;
    }

    // Function to return max profit with k transactions
    static int maxProfit(int[] prices, int k)
    {
        int n = prices.length;

        // Initialize memoization array
        int[][][] memo = new int[n][k + 1][2];
        for (int[][] arr2D : memo)
            for (int[] arr1D : arr2D)
                Arrays.fill(arr1D, -1);

        // Start from first price in 'buy' state
        return maxProfitUtil(0, k, 1, memo, prices);
    }

    public static void main(String[] args)
    {
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };

        System.out.println(maxProfit(prices, k));
    }
}
Python
# Utility function to calculate max profit
def maxProfitUtil(i, k, buy, memo, prices):

    # Base case: no transactions or end of list
    if k <= 0 or i >= len(prices):
        return 0

    if memo[i][k][buy] != -1:
        return memo[i][k][buy]

    result = 0
    profit = 0

    # If we are in a 'buy' state
    if buy == 1:

        # Buy at current price or skip
        profit = maxProfitUtil(i + 1, k, 0, memo,
                               prices) - prices[i]
        result = max(result, profit)
    else:

        # Sell at current price
        profit = prices[i] + maxProfitUtil(i + 1,
                                           k - 1, 1, memo, prices)
        result = max(result, profit)

    # Skip current price
    profit = maxProfitUtil(i + 1, k, buy, memo,
                           prices)
    result = max(result, profit)

    memo[i][k][buy] = result
    return result

# Function to return max profit with k transactions


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

    # Initialize memoization array
    memo = [[[-1] * 2 for _ in range(k + 1)]
            for _ in range(n)]

    # Start from first price in 'buy' state
    return maxProfitUtil(0, k, 1, memo, prices)


if __name__ == "__main__":
    k = 2
    prices = [10, 22, 5, 80]
    print(maxProfit(prices, k))
C#
using System;

class GfG {

    // Utility function to calculate max profit
    static int MaxProfitUtil(int i, int k, int buy,
                             int[, , ] memo, int[] prices)
    {

        // Base case: no transactions or end of list
        if (k <= 0 || i >= prices.Length)
            return 0;

        if (memo[i, k, buy] != -1)
            return memo[i, k, buy];

        int result = 0, profit = 0;

        // If we are in a 'buy' state
        if (buy == 1) {

            // Buy at current price or skip
            profit
                = MaxProfitUtil(i + 1, k, 0, memo, prices)
                  - prices[i];
            result = Math.Max(result, profit);
        }
        else {
            // Sell at current price
            profit = prices[i]
                     + MaxProfitUtil(i + 1, k - 1, 1, memo,
                                     prices);
            result = Math.Max(result, profit);
        }

        // Skip current price
        profit = MaxProfitUtil(i + 1, k, buy, memo, prices);
        result = Math.Max(result, profit);

        memo[i, k, buy] = result;
        return result;
    }

    // Function to return max profit with k
    // transactions
    static int maxProfit(int[] prices, int k)
    {
        int n = prices.Length;

        // Initialize memoization array
        int[, , ] memo = new int[n, k + 1, 2];
        for (int i = 0; i < n; i++)
            for (int j = 0; j <= k; j++)
                for (int b = 0; b < 2; b++)
                    memo[i, j, b] = -1;

        // Start from first price in 'buy' state
        return MaxProfitUtil(0, k, 1, memo, prices);
    }

    static void Main()
    {
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };

        Console.WriteLine(maxProfit(prices, k));
    }
}
JavaScript
function maxProfitUtil(i, k, buy, memo, prices)
{

    // Base case: if no transactions left or
    //  end of price list is reached
    if (k <= 0 || i >= prices.length)
        return 0;

    if (memo[i][k][buy] !== -1)
        return memo[i][k][buy];

    let result = 0, profit = 0;

    // If we are in a 'buy' state
    if (buy) {

        // Calculate profit by either buying
        // at current price or skipping
        profit = maxProfitUtil(i + 1, k, 0, memo, prices)
                 - prices[i];
        result = Math.max(result, profit);
    }
    else {

        // If in a 'sell' state, calculate profit
        //  by selling at current price
        profit = prices[i]
                 + maxProfitUtil(i + 1, k - 1, 1, memo,
                                 prices);
        result = Math.max(result, profit);
    }

    // Consider the option to skip the current price
    profit = maxProfitUtil(i + 1, k, buy, memo, prices);
    result = Math.max(result, profit);

    return memo[i][k][buy] = result;
}

// Function to return max profit from k transactions
function maxProfit(prices, k)
{
    const n = prices.length;

    // Initialize 3D array for memoization
    const memo = Array.from(
        {length : n + 1},
        () => Array.from({length : k + 1},
                         () => Array(2).fill(-1)));

    // Start from first price, in 'buy' state
    return maxProfitUtil(0, k, 1, memo, prices);
}

const k = 2;
const prices = [ 10, 22, 5, 80 ];
console.log(maxProfit(prices, k));

Output
87

Time Complexity: O(n*k)
Auxiliary Space: O(n*k)

[Better Approach-2] Using Bottom Up DP - O(n*k) time and O(n*k) space

The above solution can be further optimized using an iterative dynamic programming approach. Let dp[i][l][buy] represent the maximum profit achievable starting from day i, with l transactions remaining, and a state indicating whether we can buy or sell:

  • buy = 1 → We are allowed to buy.
  • buy = 0 → We are allowed to sell.

Recurrence Relation:

  • Buy state (buy = 1): dp[i][l][1] = max(dp[i+1][l][0] – prices[i], dp[i+1][l][1])
  • Sell state (buy = 0): dp[i][l][0] = max(prices[i] + dp[i+1][l-1][1], dp[i+1][l][0])

This iterative approach helps eliminate redundant recursive calls and improves efficiency.


C++
#include <bits/stdc++.h>
using namespace std;

// Function to return max profit from k
// transactions
int maxProfit(vector<int> &prices, int k){
    int n = prices.size();
    if (n == 0 || k == 0)
        return 0;

    // DP table to store the maximum profit:
    // dp[day][l][buy_or_sell]
    vector<vector<vector<int>>> dp(n + 1,
         vector<vector<int>>(k + 1, 
                             vector<int>(2, 0)));

    // Iterate from last day to the first (bottom-up)
    for (int i = n - 1; i >= 0; i--){
        for (int l = 1; l <= k; l++){

            // Buy state
            dp[i][l][1] = max(dp[i + 1][l][0] 
                      - prices[i], dp[i + 1][l][1]);

            // Sell state
            dp[i][l][0] = max(prices[i] 
            + dp[i + 1][l - 1][1], dp[i + 1][l][0]);
        }
    }

    // Result is maximum profit starting from day 0,
    // with k transactions, and in buy state
    return dp[0][k][1];
}

int main(){
    int k = 2;
    vector<int> prices = {10, 22, 5, 80};
    cout << maxProfit(prices, k) << endl;

    return 0;
}
Java
class GfG {

    // Function to return max profit from k
    // transactions
    static int maxProfit(int[] prices, int k){
        int n = prices.length;
        if (n == 0 || k == 0)
            return 0;

        // DP table
        int[][][] dp = new int[n + 1][k + 1][2];

        // Iterate from last day to first
        for (int i = n - 1; i >= 0; i--) {
            for (int l = 1; l <= k; l++) {
              
                // Buy state
                dp[i][l][1] = Math.max(dp[i + 1][l][0] - prices[i], dp[i + 1][l][1]);

                // Sell state
                dp[i][l][0] = Math.max(prices[i] + dp[i + 1][l - 1][1], dp[i + 1][l][0]);
            }
        }

        return dp[0][k][1];
    }

    public static void main(String[] args){
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };
        System.out.println(maxProfit(prices, k));
    }
}
Python
# Function to return max profit from k transactions
def maxProfit(prices, k):
    n = len(prices)
    if n == 0 or k == 0:
        return 0

    # DP table
    dp = [[[0] * 2 for _ in range(k + 1)]
          for _ in range(n + 1)]

    # Iterate from last day to first
    for i in range(n - 1, -1, -1):
        for l in range(1, k + 1):
          
            # Buy state
            dp[i][l][1] = max(dp[i + 1][l][0] -
                    prices[i], dp[i + 1][l][1])

            # Sell state
            dp[i][l][0] = max(prices[i] +
              dp[i + 1][l - 1][1], dp[i + 1][l][0])

    return dp[0][k][1]


if __name__ == "__main__":
    k = 2
    prices = [10, 22, 5, 80]
    print(maxProfit(prices, k))
C#
using System;

class GfG {
  
    // Function to return max profit from k 
    // transactions
    static int maxProfit(int[] prices, int k)
    {
        int n = prices.Length;
        if (n == 0 || k == 0)
            return 0;

        // DP table
        int[, , ] dp = new int[n + 1, k + 1, 2];

        // Iterate from last day to first
        for (int i = n - 1; i >= 0; i--) {
            for (int l = 1; l <= k; l++) {
              
                // Buy state
                dp[i, l, 1]
                    = Math.Max(dp[i + 1, l, 0] -
                      prices[i], dp[i + 1, l, 1]);

                // Sell state
                dp[i, l, 0] = Math.Max(
                    prices[i] + dp[i + 1, l - 1, 1],
                    dp[i + 1, l, 0]);
            }
        }

        return dp[0, k, 1];
    }

    static void Main(){
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };
        Console.WriteLine(maxProfit(prices, k));
    }
}
JavaScript
// Function to return max profit from k
// transactions
function maxProfit(prices, k)
{
    let n = prices.length;
    if (n === 0 || k === 0)
        return 0;

    // DP table
    let dp = Array.from({ length : n + 1},
             () => Array.from({length : k + 1},
                    () => Array(2).fill(0)));

    // Iterate from last day to first
    for (let i = n - 1; i >= 0; i--) {
        for (let l = 1; l <= k; l++) {
        
            // Buy state
            dp[i][l][1] = Math.max(dp[i + 1][l][0] - 
                        prices[i], dp[i + 1][l][1]);

            // Sell state
            dp[i][l][0] = Math.max(prices[i] +
                dp[i + 1][l - 1][1], dp[i + 1][l][0]);
        }
    }

    return dp[0][k][1];
}

let k = 2;
let prices = [ 10, 22, 5, 80 ];
console.log(maxProfit(prices, k));

Output
87

Time Complexity: O(n*k)
Auxiliary Space: O(n*k)

[Expected Approach] Space Optimized - O(n*k) time and O(k) space

Since for any day i, the calculations for dp[i][l][buy] only depend on dp[i+1][][] (the next day), we don’t need to store results for all previous days. Instead, we can reduce the DP table to just two 2D arrays:

  • curr[l][buy] → Represents the profit on the current day for l transactions remaining and whether we are in a buy or sell state.
  • next[l][buy] → Represents the profit for the next day.

This iterative approach optimizes space complexity, reducing it from O(k * n) to O(k) by only storing results for the current and next day instead of maintaining a full k × n DP table.

Optimized Recurrence Relation:

  • Buy state: curr[l][1] = max(-prices[i] + next[l][0], next[l][1])
  • Sell state: curr[l][0] = max(prices[i] + next[l-1][1], next[l][0])
C++
#include <bits/stdc++.h>
using namespace std;

// Function to return max profit from k transactions
int maxProfit(vector<int> &prices, int k){
    int n = prices.size();
    if (n == 0 || k == 0)
        return 0;

    vector<vector<int>> curr(k + 1, vector<int>(2, 0));
    vector<vector<int>> next(k + 1, vector<int>(2, 0));

    // Iterate from the last day to the first
    for (int i = n - 1; i >= 0; i--){
        for (int l = 1; l <= k; l++){
          
            // Calculate for buy state
            curr[l][1] = max(-prices[i] + next[l][0], next[l][1]);
          
            // Calculate for sell state
            curr[l][0] = max(prices[i] + next[l - 1][1], next[l][0]);
        }
        // Move current state to next, for the next iteration
        next = curr;
    }

    return curr[k][1];
}

int main(){
    int k = 2;
    vector<int> prices = {10, 22, 5, 80};
    cout << maxProfit(prices, k) << endl;

    return 0;
}
Java
class GfG {
  
    // Function to return max profit from k transactions
    static int maxProfit(int[] prices, int k) {
        int n = prices.length;
        if (n == 0 || k == 0)
            return 0;

        int[][] curr = new int[k+1][2];
        int[][] next = new int[k+1][2];

        // Iterate from last day to first
        for (int i = n - 1; i >= 0; i--) {
            for (int l = 1; l <= k; l++) {
              
                // Calculate for buy state
                curr[l][1] = Math.max(-prices[i] + next[l][0], next[l][1]);

                // Calculate for sell state
                curr[l][0] = Math.max(prices[i] + next[l-1][1], next[l][0]);
            }
          
            // Move curr to next for next iteration
            for (int l = 0; l <= k; l++) {
                next[l][0] = curr[l][0];
                next[l][1] = curr[l][1];
            }
        }
      
        
        return curr[k][1]; 
    }

    public static void main(String[] args) {
        int k = 2;
        int[] prices = {10, 22, 5, 80};
        System.out.println(maxProfit(prices, k));
    }
}
Python
# Function to return max profit from k
# transactions
def maxProfit(prices, k):
    n = len(prices)
    if n == 0 or k == 0:
        return 0

    curr = [[0] * 2 for _ in range(k+1)]
    next = [[0] * 2 for _ in range(k+1)]

    # Iterate from last day to first
    for i in range(n-1, -1, -1):
        for l in range(1, k+1):
          
            # Calculate for buy state
            curr[l][1] = max(-prices[i] + next[l][0], next[l][1])
            
            # Calculate for sell state
            curr[l][0] = max(prices[i] + next[l-1][1], next[l][0])
            
        # Move curr to next for next iteration
        next = [row[:] for row in curr]
        
    # The result is the maximum profit starting
    # from day 0, with k transactions, and in 
    # buy state = 1 (this shows that transaction 
    # has been completed)
    return curr[k][1] 

if __name__ == "__main__":
    k = 2
    prices = [10, 22, 5, 80]
    print(maxProfit(prices, k))
C#
using System;

class GfG {
  
    // Function to return max profit from k
    // transactions
    static int maxProfit(int[] prices, int k) {
        int n = prices.Length;
        if (n == 0 || k == 0)
            return 0;

        int[,] curr = new int[k+1, 2];
        int[,] next = new int[k+1, 2];

        // Iterate from last day to first
        for (int i = n - 1; i >= 0; i--) {
            for (int l = 1; l <= k; l++) {
              
                // Calculate for buy state
                curr[l, 1] = Math.Max(next[l, 0] -
                           prices[i], next[l, 1]);

                // Calculate for sell state
                curr[l, 0] = Math.Max(prices[i] +
                        next[l - 1, 1], next[l, 0]);
            }
          
            // Move curr to next for next iteration
            for (int l = 0; l <= k; l++) {
                next[l, 0] = curr[l, 0];
                next[l, 1] = curr[l, 1];
            }
        }
        
        // The result is the maximum profit starting
        // from day 0, with k transactions, and in 
        // buy state = 1 (this shows that transaction 
        // has been completed)
        return curr[k, 1];  
    }

    static void Main() {
        int k = 2;
        int[] prices = { 10, 22, 5, 80 };
        Console.WriteLine(maxProfit(prices, k));
    }
}
JavaScript
// Function to return max profit from k transactions
function maxProfit(prices, k) {
    let n = prices.length;
    if (n === 0 || k === 0) return 0;
    
    let curr = Array.from({ length: k + 1 }, () => 
        Array(2).fill(0));
        
    let next = Array.from({ length: k + 1 }, () =>
        Array(2).fill(0));

    // Iterate from last day to first
    for (let i = n - 1; i >= 0; i--) {
        for (let l = 1; l <= k; l++) {
        
            // Calculate for buy state
            curr[l][1] = Math.max(-prices[i]
                     + next[l][0], next[l][1]);
                     
            // Calculate for sell state
            curr[l][0] = Math.max(prices[i] +
                   next[l - 1][1], next[l][0]);
        }
        
        // Move curr to next for next iteration
        next = curr.map(row => row.slice());
    }
	
    return curr[k][1];
}

let k = 2;
let prices = [10, 22, 5, 80];
console.log(maxProfit(prices, k));

Output
87

Time Complexity: O(n*k)
Auxiliary Space: O(k)



Similar Reads