Saturday, November 16, 2024
Google search engine
HomeData Modelling & AIMaximum profit by buying and selling a share at most k times

Maximum profit by buying and selling a share at most k times

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, 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:  
Price = [10, 22, 5, 75, 65, 80]
K = 2
Output: 87
Trader earns 87 as sum of 12 and 75
Buy at price 10, sell at 22, buy at
5 and sell at 80
Input:
Price = [12, 14, 17, 10, 14, 13, 12, 15]
K = 3
Output: 12
Trader earns 12 as the sum of 5, 4 and 3
Buy at price 12, sell at 17, buy at 10
and sell at 14 and buy at 12 and sell
at 15

Input:
Price = [100, 30, 15, 10, 8, 25, 80]
K = 3
Output: 72
Only one transaction. Buy at price 8
and sell at 80.
Input:
Price = [90, 80, 70, 60, 50]
K = 1
Output: 0
Not possible to earn.

There are various versions of the problem. If we are allowed to buy and sell only once, then we can use the Maximum difference between the two elements algorithm. If we are allowed to make at most 2 transactions, we can follow approach discussed here. If we are allowed to buy and sell any number of times, we can follow approach discussed here.
 

Recommended Practice

Method 1 Dynamic Programming

In this post, we are only allowed to make at max k transactions. The problem can be solved by using dynamic programming. 

Let profit[t][i] represent maximum profit using at most t transactions up to day i (including day i). Then the relation is:
profit[t][i] = max(profit[t][i-1], max(price[i] – price[j] + profit[t-1][j])) 
          for all j in range [0, i-1] 
profit[t][i] will be maximum of – 

  1. profit[t][i-1] which represents not doing any transaction on the ith day.
  2. Maximum profit gained by selling on ith day. In order to sell shares on ith day, we need to purchase it on any one of [0, i – 1] days. If we buy shares on jth day and sell it on ith day, max profit will be price[i] – price[j] + profit[t-1][j] where j varies from 0 to i-1. Here profit[t-1][j] is best we could have done with one less transaction till jth day.

Below is Dynamic Programming based implementation

C++




// C++ program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
#include <climits>
#include <iostream>
using namespace std;
 
// Function to find out maximum profit by buying
// & selling a share atmost k times given stock
// price of n days
int maxProfit(int price[], int n, int k)
{
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using
    // atmost t transactions up to day i (including
    // day i)
    int profit[k + 1][n + 1];
 
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for (int i = 0; i <= k; i++)
        profit[i][0] = 0;
 
    // profit is 0 if we don't do any transaction
    // (i.e. k =0)
    for (int j = 0; j <= n; j++)
        profit[0][j] = 0;
 
    // fill the table in bottom-up fashion
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j < n; j++) {
            int max_so_far = INT_MIN;
 
            for (int m = 0; m < j; m++)
                max_so_far = max(max_so_far,
                                 price[j] - price[m] + profit[i - 1][m]);
 
            profit[i][j] = max(profit[i][j - 1], max_so_far);
        }
    }
 
    return profit[k][n - 1];
}
 
// Driver code
int main()
{
    int k = 2;
    int price[] = { 10, 22, 5, 75, 65, 80 };
    int n = sizeof(price) / sizeof(price[0]);
 
    cout << "Maximum profit is: "
         << maxProfit(price, n, k);
 
    return 0;
}


Java




// Java program to find out maximum
// profit by buying and selling a
// share atmost k times given
// stock price of n days
 
class GFG {
     
    // Function to find out
    // maximum profit by
    // buying & selling a
    // share atmost k times
    // given stock price of n days
    static int maxProfit(int[] price,
                         int n,
                         int k)
    {
         
        // table to store results
        // of subproblems
        // profit[t][i] stores
        // maximum profit using
        // atmost t transactions up
        // to day i (including day i)
        int[][] profit = new int[k + 1][n + 1];
 
        // For day 0, you can't
        // earn money irrespective
        // of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i][0] = 0;
 
        // profit is 0 if we don't
        // do any transaction
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0][j] = 0;
 
        // fill the table in
        // bottom-up fashion
        for (int i = 1; i <= k; i++)
        {
            for (int j = 1; j < n; j++)
            {
                int max_so_far = 0;
 
                for (int m = 0; m < j; m++)
                max_so_far = Math.max(max_so_far, price[j] -
                             price[m] + profit[i - 1][m]);
 
                profit[i][j] = Math.max(profit[i] [j - 1],
                                              max_so_far);
            }
        }
 
        return profit[k][n - 1];
    }
 
    // Driver code
    public static void main(String []args)
    {
        int k = 2;
        int[] price = { 10, 22, 5, 75, 65, 80 };
        int n = price.length;
        System.out.println("Maximum profit is: " +
                            maxProfit(price, n, k));
    }
}
 
// This code is contributed by Anshul Aggarwal.


Python3




# Python program to maximize the profit
# by doing at most k transactions
# given stock prices for n days
 
# Function to find out maximum profit by
# buying & selling a share atmost k times
# given stock price of n days
def maxProfit(prices, n, k):
     
    # Bottom-up DP approach
    profit = [[0 for i in range(k + 1)]
                 for j in range(n)]
     
    # Profit is zero for the first
    # day and for zero transactions
    for i in range(1, n):
         
        for j in range(1, k + 1):
            max_so_far = 0
             
            for l in range(i):
                max_so_far = max(max_so_far, prices[i] -
                            prices[l] + profit[l][j - 1])
                             
            profit[i][j] = max(profit[i - 1][j], max_so_far)
     
    return profit[n - 1][k]
 
# Driver code
k = 2
prices = [10, 22, 5, 75, 65, 80]
n = len(prices)
 
print("Maximum profit is:",
       maxProfit(prices, n, k))
 
# This code is contributed by vaibhav29498


C#




// C# program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
using System;
 
class GFG {
     
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times
    // given stock price of n days
    static int maxProfit(int[] price, int n, int k)
    {
        // table to store results of subproblems
        // profit[t][i] stores maximum profit using atmost
        // t transactions up to day i (including day i)
        int[, ] profit = new int[k + 1, n + 1];
 
        // For day 0, you can't earn money
        // irrespective of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i, 0] = 0;
 
        // profit is 0 if we don't do any transaction
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0, j] = 0;
 
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++) {
            for (int j = 1; j < n; j++) {
                int max_so_far = 0;
 
                for (int m = 0; m < j; m++)
                max_so_far = Math.Max(max_so_far, price[j] -
                               price[m] + profit[i - 1, m]);
 
                profit[i, j] = Math.Max(profit[i, j - 1], max_so_far);
            }
        }
 
        return profit[k, n - 1];
    }
 
    // Driver code to test above
    public static void Main()
    {
        int k = 2;
        int[] price = { 10, 22, 5, 75, 65, 80 };
 
        int n = price.Length;
 
        Console.Write("Maximum profit is: " +
                     maxProfit(price, n, k));
    }
}
 
// This code is contributed by Sam007


Javascript




<script>
 
// javascript program to find out maximum
// profit by buying and selling a
// share atmost k times given
// stock price of n days 
 
// Function to find out
// maximum profit by
// buying & selling a
// share atmost k times
// given stock price of n days
function maxProfit(price,n, k)
{
     
    // table to store results
    // of subproblems
    // profit[t][i] stores
    // maximum profit using
    // atmost t transactions up
    // to day i (including day i)
    var profit = Array(k+1).fill(0).map
    (x => Array(n+1).fill(0));
 
    // For day 0, you can't
    // earn money irrespective
    // of how many times you trade
    for (i = 0; i <= k; i++)
        profit[i][0] = 0;
 
    // profit is 0 if we don't
    // do any transaction
    // (i.e. k =0)
    for (j = 0; j <= n; j++)
        profit[0][j] = 0;
 
    // fill the table in
    // bottom-up fashion
    for (i = 1; i <= k; i++)
    {
        for (j = 1; j < n; j++)
        {
            var max_so_far = 0;
 
            for (m = 0; m < j; m++)
            max_so_far = Math.max(max_so_far, price[j] -
                         price[m] + profit[i - 1][m]);
 
            profit[i][j] = Math.max(profit[i] [j - 1],
                                          max_so_far);
        }
    }
 
    return profit[k][n - 1];
}
 
// Driver code
var k = 2;
var price = [ 10, 22, 5, 75, 65, 80 ];
var n = price.length;
document.write("Maximum profit is: " +
                    maxProfit(price, n, k));
 
 
// This code contributed by shikhasingrajput
 
</script>


PHP




<?php
// PHP program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
 
// Function to find out maximum profit by buying
// & selling a share atmost k times given stock
// price of n days
function maxProfit($price, $n, $k)
{
     
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using
    // atmost t transactions up to day i (including
    // day i)
    $profit[$k + 1][$n + 1] = 0;
     
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for ($i = 0; $i <= $k; $i++)
        $profit[$i][0] = 0;
 
    // profit is 0 if we don't
    // do any transaction
    // (i.e. k =0)
    for ($j = 0; $j <= $n; $j++)
        $profit[0][$j] = 0;
 
    // fill the table in
    // bottom-up fashion
    for ($i = 1; $i <= $k; $i++) {
        for ($j = 1; $j < $n; $j++) {
            $max_so_far = PHP_INT_MIN;
 
            for ($m = 0; $m < $j; $m++)
                $max_so_far = max($max_so_far,
                              $price[$j] - $price[$m] +
                              $profit[$i - 1][$m]);
 
            $profit[$i][$j] = max($profit[$i][$j - 1],
                                         $max_so_far);
        }
    }
 
    return $profit[$k][$n - 1];
}
 
    // Driver code
    $k = 2;
    $price = array (10, 22, 5, 75, 65, 80 );
    $n = sizeof($price);
    echo "Maximum profit is: ". maxProfit($price, $n, $k);
 
// This is contributed by mits
?>


Output

Maximum profit is: 87

Space Complexity: O(n*k) since we are using a 2-D array.
Time Complexity: O(k.n2). It can be reduced if we are able to calculate the maximum profit gained by selling shares on the ith day in constant time.
profit[t][i] = max(profit [t][i-1], max(price[i] – price[j] + profit[t-1][j])) 
                            for all j in range [0, i-1]
If we carefully notice, 
max(price[i] – price[j] + profit[t-1][j]) 
for all j in range [0, i-1]
can be rewritten as, 
= price[i] + max(profit[t-1][j] – price[j]) 
for all j in range [0, i-1] 
= price[i] + max(prevDiff, profit[t-1][i-1] – price[i-1]) 
where prevDiff is max(profit[t-1][j] – price[j]) 
for all j in range [0, i-2]
So, if we have already calculated max(profit[t-1][j] – price[j]) for all j in range [0, i-2], we can calculate it for j = i – 1 in constant time. In other words, we don’t have to look back in the range [0, i-1] anymore to find out best day to buy. We can determine that in constant time using below revised relation.
profit[t][i] = max(profit[t][i-1], price[i] + max(prevDiff, profit [t-1][i-1] – price[i-1]) 
where prevDiff is max(profit[t-1][j] – price[j]) for all j in range [0, i-2]

Below is its optimized implementation – 

C++




// C++ program to find out maximum profit by buying
// and/ selling a share atmost k times given stock
// price of n days
#include <climits>
#include <iostream>
using namespace std;
 
// Function to find out maximum profit by buying &
// selling/ a share atmost k times given stock price
// of n days
int maxProfit(int price[], int n, int k)
{
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using atmost
    // t transactions up to day i (including day i)
    int profit[k + 1][n + 1];
 
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for (int i = 0; i <= k; i++)
        profit[i][0] = 0;
 
    // profit is 0 if we don't do any transaction
    // (i.e. k =0)
    for (int j = 0; j <= n; j++)
        profit[0][j] = 0;
 
    // fill the table in bottom-up fashion
    for (int i = 1; i <= k; i++) {
        int prevDiff = INT_MIN;
        for (int j = 1; j < n; j++) {
            prevDiff = max(prevDiff,
                           profit[i - 1][j - 1] - price[j - 1]);
            profit[i][j] = max(profit[i][j - 1],
                               price[j] + prevDiff);
        }
    }
 
    return profit[k][n - 1];
}
 
// Driver Code
int main()
{
    int k = 3;
    int price[] = { 12, 14, 17, 10, 14, 13, 12, 15 };
 
    int n = sizeof(price) / sizeof(price[0]);
 
    cout << "Maximum profit is: "
         << maxProfit(price, n, k);
 
    return 0;
}


Java




// Java program to find out maximum
// profit by buying and selling a
// share atmost k times given stock
// price of n days
import java.io.*;
 
class GFG {
     
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times
    // given stock price of n days
    static int maxProfit(int price[],
                         int n, int k)
    {
         
        // table to store results of subproblems
        // profit[t][i] stores maximum profit
        // using atmost t transactions up to day
        // i (including day i)
        int profit[][] = new int[k + 1][ n + 1];
 
        // For day 0, you can't earn money
        // irrespective of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i][0] = 0;
 
        // profit is 0 if we don't do any
        // transaction (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0][j] = 0;
 
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++)
        {
            int prevDiff = Integer.MIN_VALUE;
            for (int j = 1; j < n; j++)
            {
                prevDiff = Math.max(prevDiff,
                           profit[i - 1][j - 1] -
                           price[j - 1]);
                profit[i][j] = Math.max(profit[i][j - 1],
                               price[j] + prevDiff);
            }
        }
 
        return profit[k][n - 1];
    }
 
// Driver code
public static void main (String[] args)
    {
        int k = 3;
        int price[] = {12, 14, 17, 10, 14, 13, 12, 15};
 
        int n = price.length;
 
        System.out.println("Maximum profit is: " +
                            maxProfit(price, n, k));
    }
}
 
// This code is contributed by Sam007


Python3




# Python3 program to find out maximum
# profit by buying and/ selling a share
# at most k times given the stock price
# of n days
 
# Function to find out maximum profit
# by buying & selling/ a share atmost
# k times given stock price of n days
def maxProfit(price, n, k):
 
    # Table to store results of subproblems
    # profit[t][i] stores maximum profit
    # using atmost t transactions up to
    # day i (including day i)
    profit = [[0 for i in range(n + 1)]
                 for j in range(k + 1)]
 
    # Fill the table in bottom-up fashion
    for i in range(1, k + 1):
        prevDiff = float('-inf')
         
        for j in range(1, n):
            prevDiff = max(prevDiff,
                           profit[i - 1][j - 1] -
                           price[j - 1])
            profit[i][j] = max(profit[i][j - 1],
                               price[j] + prevDiff)
 
    return profit[k][n - 1]
 
# Driver Code
if __name__ == "__main__":
 
    k = 3
    price = [12, 14, 17, 10, 14, 13, 12, 15]
    n = len(price)
 
    print("Maximum profit is:",
           maxProfit(price, n, k))
 
# This code is contributed
# by Rituraj Jain


C#




// C# program to find out maximum profit by buying
// and selling a share atmost k times given stock
// price of n days
using System;
 
class GFG {
     
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times
    // given stock price of n days
    static int maxProfit(int[] price, int n, int k)
    {
        // table to store results of subproblems
        // profit[t][i] stores maximum profit using atmost
        // t transactions up to day i (including day i)
        int[, ] profit = new int[k + 1, n + 1];
 
        // For day 0, you can't earn money
        // irrespective of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i, 0] = 0;
 
        // profit is 0 if we don't do any transaction
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0, j] = 0;
 
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++) {
            int prevDiff = int.MinValue;
            for (int j = 1; j < n; j++) {
            prevDiff = Math.Max(prevDiff,
                            profit[i - 1, j - 1] - price[j - 1]);
            profit[i, j] = Math.Max(profit[i, j - 1],
                                price[j] + prevDiff);
            }
        }
 
        return profit[k, n - 1];
    }
 
    // Driver code to test above
    public static void Main()
    {
        int k = 3;
        int[] price = {12, 14, 17, 10, 14, 13, 12, 15};
 
        int n = price.Length;
 
        Console.Write("Maximum profit is: " +
                     maxProfit(price, n, k));
    }
}
 
// This code is contributed by Sam007


Javascript




<script>
 
// javascript program to find out maximum
// profit by buying and selling a
// share atmost k times given stock
// price of n days
    
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times
    // given stock price of n days
function maxProfit(price, n , k)
{
     
    // table to store results of subproblems
    // profit[t][i] stores maximum profit
    // using atmost t transactions up to day
    // i (including day i)
    var profit = Array(k+1).fill(0).map(x => Array(n+1).fill(0));
 
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for (var i = 0; i <= k; i++)
        profit[i][0] = 0;
 
    // profit is 0 if we don't do any
    // transaction (i.e. k =0)
    for (j = 0; j <= n; j++)
        profit[0][j] = 0;
 
    // fill the table in bottom-up fashion
    for (var i = 1; i <= k; i++)
    {
        var prevDiff = -Number.MAX_VALUE;
        for (var j = 1; j < n; j++)
        {
            prevDiff = Math.max(prevDiff,
                       profit[i - 1][j - 1] -
                       price[j - 1]);
            profit[i][j] = Math.max(profit[i][j - 1],
                           price[j] + prevDiff);
        }
    }
 
    return profit[k][n - 1];
}
 
// Driver code
var k = 3;
var price = [12, 14, 17, 10, 14, 13, 12, 15];
 
var n = price.length;
 
document.write("Maximum profit is: " +
                    maxProfit(price, n, k));
// This code contributed by shikhasingrajput
</script>


PHP




<?php
// PHP program to find out maximum
// profit by buying and selling a
// share atmost k times given stock
// price of n days
 
// Function to find out maximum
// profit by buying & selling a
// share atmost k times given
// stock price of n days
function maxProfit($price, $n, $k)
{
     
    // table to store results
    // of subproblems profit[t][i]
    // stores maximum profit using
    // atmost t transactions up to
    // day i (including day i)
    $profit[$k + 1][$n + 1]=0;
 
    // For day 0, you can't
    // earn money irrespective
    // of how many times you trade
    for ($i = 0; $i <= $k; $i++)
        $profit[$i][0] = 0;
 
    // profit is 0 if we don't
    // do any transaction
    // (i.e. k =0)
    for ($j = 0; $j <= $n; $j++)
        $profit[0][$j] = 0;
 
    // fill the table in
    // bottom-up fashion
    $prevDiff = NULL;
    for ($i = 1; $i <= $k; $i++) {
        for ($j = 1; $j < $n; $j++) {
            $prevDiff = max($prevDiff, $profit[$i - 1][$j - 1] -
                                               $price[$j - 1]);
            $profit[$i][$j] = max($profit[$i][$j - 1],
                              $price[$j] + $prevDiff);
        }
    }
    return $profit[$k][$n - 1];
}
 
    // Driver Code
    $k = 3;
    $price = array(12, 14, 17, 10,
                   14, 13, 12, 15);
    $n = sizeof($price);
    echo "Maximum profit is: "
         , maxProfit($price, $n, $k);
 
// This code is contributed by nitin mittal
?>


Output

Maximum profit is: 12

The time complexity of the above solution is O(kn) and space complexity is O(nk). Space complexity can further be reduced to O(n) as we use the result from the last transaction. But to make the article easily readable, we have used O(kn) space.
This article is contributed by Aditya Goel

Method-2 Memoization(dynamic Programming)

One more way we can approach this problem is by considering buying and selling as two different states of the dp. So we will consider the dp as follows:

let i be the index of the stock we are at, j be the total transaction reamaining, b represent if we have to sell or buy this stock(1 for buying and 0 for selling) and A represent the array containing stock prices then state transitions will be as follows:

dp[i][j][1]=max(-A[i]+dp[j][i+1][0],dp[j][i+1][1])

dp[i][j][0]=max(A[i]+dp[j-1][i+1][1],dp[j][i+1][0])

implementation is as follows:

C++




// C++ program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
#include <bits/stdc++.h>
using namespace std;
 
int B;
vector<int> A;
int dp[501][201][2];
int solve(int j, int i, int b)
{
    // if the result has already been calculated return that result
    if (dp[i][j][b] != -1)
        return dp[i][j][b];
    // if i has reached the end of the array return 0
    if (i == B)
        return 0;
    // if we have exhausted the number of transaction return 0
    if (j == 0)
        return 0;
    int res;
    // if we are to buy stocks
    if (b == 1)
        res = max(-A[i] + solve(j, i + 1, 0), solve(j, i + 1, 1));
    // if we are to sell stock and complete one transaction
    else
        res = max(A[i] + solve(j - 1, i + 1, 1), solve(j, i + 1, 0));
    // return the result
    return dp[i][j][b] = res;
}
int maxProfit(int K, int N, int C[])
{
    A = vector<int>(N, 0);
    // Copying C to global A
    for (int i = 0; i < N; i++)
        A[i] = C[i];
    // Initializing DP with -1
    for (int i = 0; i <= N; i++)
        for (int j = 0; j <= K; j++)
        {
            dp[i][j][1] = -1;
            dp[i][j][0] = -1;
        }
    // Copying n to global B
    B = N;
    return solve(K, 0, 1);
}
 
// driver code
int main()
{
    // TEST 1
    int k1 = 3;
    int price1[] = {12, 14, 17, 10, 14, 13, 12, 15};
    int n1 = sizeof(price1) / sizeof(price1[0]);
    cout << "Maximum profit is: "
         << maxProfit(k1, n1, price1) << endl;
    // TEST 2
    int k2 = 2;
    int price2[] = {10, 22, 5, 75, 65, 80};
    int n2 = sizeof(price2) / sizeof(price2[0]);
 
    cout << "Maximum profit is: "
         << maxProfit(k2, n2, price2);
    return 0;
}
//This code is contributed by Anirudh Singh


Java




// Java program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
import java.util.*;
 
class GFG {
    static int B;
    static ArrayList<Integer> A;
    static int dp[][][] = new int[501][201][2];
    static int solve(int j, int i, int b)
    {
       
        // if the result has already been calculated return
        // that result
        if (dp[i][j][b] != -1)
            return dp[i][j][b];
       
        // if i has reached the end of the array return 0
        if (i == B)
            return 0;
       
        // if we have exhausted the number of transaction
        // return 0
        if (j == 0)
            return 0;
        int res;
       
        // if we are to buy stocks
        if (b == 1)
            res = Math.max(-A.get(i) + solve(j, i + 1, 0),
                           solve(j, i + 1, 1));
       
        // if we are to sell stock and complete one
        // transaction
        else
            res = Math.max(A.get(i) + solve(j - 1, i + 1, 1),
                           solve(j, i + 1, 0));
       
        // return the result
        return dp[i][j][b] = res;
    }
 
    static int maxProfit(int K, int N, int C[])
    {
        A = new ArrayList<Integer>();
       
        // Copying C to global A
        for (int i = 0; i < N; i++)
            A.add(C[i]);
 
        // Initializing DP with -1
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= K; j++) {
                dp[i][j][1] = -1;
                dp[i][j][0] = -1;
            }
        // Copying n to global B
        B = N;
        return solve(K, 0, 1);
    }
 
    // driver code
    public static void main(String[] args)
    {
        // TEST 1
        int k1 = 3;
        int price1[] = { 12, 14, 17, 10, 14, 13, 12, 15 };
        int n1 = price1.length;
        System.out.println("Maximum profit is: "
                           + maxProfit(k1, n1, price1));
 
        // TEST 2
        int k2 = 2;
        int price2[] = { 10, 22, 5, 75, 65, 80 };
        int n2 = price2.length;
        System.out.println("Maximum profit is: "
                           + maxProfit(k2, n2, price2));
    }
}
 
// This code is contributed by phasing17


Python3




# Python3 program to find out maximum profit by
# buying and selling a share atmost k times
# given stock price of n days
 
A = []
dp = [None for _ in range(501)]
for i in range(501):
    dp[i] = [None for _ in range(201)]
    for j in range(201):
        dp[i][j] = [-1, -1]
 
B = len(dp)
 
 
def solve(j, i, b):
    global dp, B
 
    # if the result has already been calculated return that result
    if (dp[i][j][b] != -1):
        return dp[i][j][b]
 
    # if i has reached the end of the array return 0
    if (i == B):
        return 0
 
    # if we have exhausted the number of transaction return 0
    if (j == 0):
        return 0
 
    # if we are to buy stocks
    if (b == 1):
        res = max(-A[i] + solve(j, i + 1, 0), solve(j, i + 1, 1))
 
    # if we are to sell stock and complete one transaction
    else:
        res = max(A[i] + solve(j - 1, i + 1, 1), solve(j, i + 1, 0))
 
    # return the result
    dp[i][j][b] = res
    return res
 
 
def maxProfit(K, N, C):
    global dp, B, A
 
    A = [0 for _ in range(N)]
 
    # Copying C to global A
    A = C.copy()
 
    # Initializing DP with -1
    for i in range(N + 1):
        for j in range(K + 1):
            dp[i][j][1] = -1
            dp[i][j][0] = -1
 
    # Copying n to global B
    B = N
    return solve(K, 0, 1)
 
 
# Driver code
 
# TEST 1
k1 = 3
price1 = [12, 14, 17, 10, 14, 13, 12, 15]
n1 = len(price1)
print("Maximum profit is:", maxProfit(k1, n1, price1))
 
# TEST 2
k2 = 2
price2 = [10, 22, 5, 75, 65, 80]
n2 = len(price2)
print("Maximum profit is:", maxProfit(k2, n2, price2))
 
 
# This code is contributed by phasing17


C#




// C# program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
using System;
using System.Collections.Generic;
 
class GFG {
  static int B;
  static List<int> A;
  static int[, , ] dp = new int[501, 201, 2];
  static int solve(int j, int i, int b)
  {
 
    // if the result has already been calculated return
    // that result
    if (dp[i, j, b] != -1)
      return dp[i, j, b];
 
    // if i has reached the end of the array return 0
    if (i == B)
      return 0;
 
    // if we have exhausted the number of transaction
    // return 0
    if (j == 0)
      return 0;
    int res;
 
    // if we are to buy stocks
    if (b == 1)
      res = Math.Max(-A[i] + solve(j, i + 1, 0),
                     solve(j, i + 1, 1));
     
    // if we are to sell stock and complete one
    // transaction
    else
      res = Math.Max(A[i] + solve(j - 1, i + 1, 1),
                     solve(j, i + 1, 0));
 
    // return the result
    return dp[i, j, b] = res;
  }
 
  static int maxProfit(int K, int N, int[] C)
  {
    A = new List<int>();
 
    // Copying C to global A
    for (int i = 0; i < N; i++)
      A.Add(C[i]);
 
    // Initializing DP with -1
    for (int i = 0; i <= N; i++)
      for (int j = 0; j <= K; j++) {
        dp[i, j, 1] = -1;
        dp[i, j, 0] = -1;
      }
    // Copying n to global B
    B = N;
    return solve(K, 0, 1);
  }
 
  // driver code
  public static void Main(string[] args)
  {
    // TEST 1
    int k1 = 3;
    int[] price1 = { 12, 14, 17, 10, 14, 13, 12, 15 };
    int n1 = price1.Length;
    Console.WriteLine("Maximum profit is: "
                      + maxProfit(k1, n1, price1));
 
    // TEST 2
    int k2 = 2;
    int[] price2 = { 10, 22, 5, 75, 65, 80 };
    int n2 = price2.Length;
    Console.WriteLine("Maximum profit is: "
                      + maxProfit(k2, n2, price2));
  }
}
 
// This code is contributed by phasing17


Javascript




// JavaScript program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
 
let B;
let A = [];
let dp = new Array(501);
for (let i = 0; i < 501; i++)
{
    dp[i] = new Array(201);
    for (let j = 0; j < 201; j++)
        dp[i][j] = new Array(2);
}
 
function solve(j, i, b)
{
    // if the result has already been calculated return that result
    if (dp[i][j][b] != -1)
        return dp[i][j][b];
    // if i has reached the end of the array return 0
    if (i == B)
        return 0;
    // if we have exhausted the number of transaction return 0
    if (j == 0)
        return 0;
    let res;
    // if we are to buy stocks
    if (b == 1)
        res = Math.max(-A[i] + solve(j, i + 1, 0), solve(j, i + 1, 1));
    // if we are to sell stock and complete one transaction
    else
        res = Math.max(A[i] + solve(j - 1, i + 1, 1), solve(j, i + 1, 0));
    // return the result
    return dp[i][j][b] = res;
}
 
function maxProfit(K, N, C)
{
    A = new Array(N).fill(0);
    // Copying C to global A
    for (i = 0; i < N; i++)
        A[i] = C[i];
    // Initializing DP with -1
    for (i = 0; i <= N; i++)
        for (j = 0; j <= K; j++)
        {
            dp[i][j][1] = -1;
            dp[i][j][0] = -1;
        }
    // Copying n to global B
    B = N;
    return solve(K, 0, 1);
}
 
// driver code
 
// TEST 1
let k1 = 3;
let price1 = [12, 14, 17, 10, 14, 13, 12, 15];
let n1 = price1.length;
console.log("Maximum profit is: " + maxProfit(k1, n1, price1));
     
// TEST 2
let k2 = 2;
let price2 = [10, 22, 5, 75, 65, 80];
let n2 = price2.length;
 
console.log("Maximum profit is: " + maxProfit(k2, n2, price2));
     
     
//This code is contributed by phasing17


Output

Maximum profit is: 12
Maximum profit is: 87

Time Complexity: O(n*k)
Auxiliary Space: O(n*k), since n*k extra space has been taken.

This approach and implementation is contributed by Anirudh Singh.

Naive Recursive Approach:

C++




// C++ program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
#include <climits>
#include <iostream>
using namespace std;
 
// Function to find out maximum profit by buying
// & selling a share atmost k times given stock
// price of n days
int f(int idx, int buy, int prices[], int cap, int n)
{
    if (cap == 0) {
        return 0;
    }
 
    if (idx == n) {
        return 0;
    }
 
    int profit = 0;
    // you can either buy or not buy
    if (buy == 0) {
        profit = max(-prices[idx]
                         + f(idx + 1, 1, prices, cap, n),
                     f(idx + 1, 0, prices, cap, n));
    }
    // you can either sell or not sell
    else {
        profit = max(
            prices[idx] + f(idx + 1, 0, prices, cap - 1, n),
            f(idx + 1, 1, prices, cap, n));
    }
 
    return profit;
}
 
int maxProfit(int prices[], int n, int k)
{
 
    return f(0, 0, prices, k, n);
}
 
// Driver code
int main()
{
    int k = 2;
    int price[] = { 10, 22, 5, 75, 65, 80 };
    int n = sizeof(price) / sizeof(price[0]);
 
    cout << "Maximum profit is: " << maxProfit(price, n, k);
 
    return 0;
}


Java




// Java program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
import java.util.*;
 
class Main {
    static int f(int idx, int buy, int[] prices, int cap,
                 int n)
    {
        if (cap == 0) {
            return 0;
        }
        if (idx == n) {
            return 0;
        }
 
        int profit = 0;
        // you can either buy or not buy
        if (buy == 0) {
            profit = Math.max(
                -prices[idx]
                    + f(idx + 1, 1, prices, cap, n),
                f(idx + 1, 0, prices, cap, n));
        }
        // you can either sell or not sell
        else {
            profit = Math.max(
                prices[idx]
                    + f(idx + 1, 0, prices, cap - 1, n),
                f(idx + 1, 1, prices, cap, n));
        }
 
        return profit;
    }
 
    static int maxProfit(int[] prices, int n, int k)
    {
        return f(0, 0, prices, k, n);
    }
 
    public static void main(String[] args)
    {
        int k = 2;
        int[] price = { 10, 22, 5, 75, 65, 80 };
        int n = price.length;
 
        System.out.println("Maximum profit is: "
                           + maxProfit(price, n, k));
    }
}


Python3




# Python program to find out maximum profit by
# buying and selling a share atmost k times
# given stock price of n days
 
def f(idx, buy, prices, cap, n):
    if cap == 0:
        return 0
 
    if idx == n:
        return 0
 
    profit = 0
    # you can either buy or not buy
    if buy == 0:
        profit = max(-prices[idx] + f(idx + 1, 1, prices, cap, n),
                     f(idx + 1, 0, prices, cap, n))
    # you can either sell or not sell
    else:
        profit = max(prices[idx] + f(idx + 1, 0, prices, cap - 1, n),
                     f(idx + 1, 1, prices, cap, n))
 
    return profit
 
def maxProfit(prices, n, k):
    return f(0, 0, prices, k, n)
 
# Driver code
if __name__ == "__main__":
    k = 2
    price = [10, 22, 5, 75, 65, 80]
    n = len(price)
 
    print("Maximum profit is:", maxProfit(price, n, k))


C#




// C# program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
using System;
 
class GFG {
  static int f(int idx, int buy, int[] prices, int cap,
               int n)
  {
    if (cap == 0) {
      return 0;
    }
    if (idx == n) {
      return 0;
    }
 
    int profit = 0;
    // you can either buy or not buy
    if (buy == 0) {
      profit = Math.Max(
        -prices[idx]
        + f(idx + 1, 1, prices, cap, n),
        f(idx + 1, 0, prices, cap, n));
    }
    // you can either sell or not sell
    else {
      profit = Math.Max(
        prices[idx]
        + f(idx + 1, 0, prices, cap - 1, n),
        f(idx + 1, 1, prices, cap, n));
    }
 
    return profit;
  }
 
  // function to return the maximum profit
  static int maxProfit(int[] prices, int n, int k)
  {
    return f(0, 0, prices, k, n);
  }
 
  // driver code
  public static void Main(string[] args)
  {
    int k = 2;
    int[] price = { 10, 22, 5, 75, 65, 80 };
    int n = price.Length;
 
    // function call
    Console.WriteLine("Maximum profit is: "
                      + maxProfit(price, n, k));
  }
}


Javascript




// JavaScript program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
function f(idx, buy, prices, cap, n) {
  if (cap == 0) {
    return 0;
  }
 
  if (idx == n) {
    return 0;
  }
 
  let profit = 0;
  if (buy == 0) {
    profit = Math.max(-prices[idx] + f(idx + 1, 1, prices, cap, n),
                      f(idx + 1, 0, prices, cap, n));
  } else {
    profit = Math.max(prices[idx] + f(idx + 1, 0, prices, cap - 1, n),
                      f(idx + 1, 1, prices, cap, n));
  }
 
  return profit;
}
 
function maxProfit(prices, n, k) {
  return f(0, 0, prices, k, n);
}
 
let k = 2;
let price = [10, 22, 5, 75, 65, 80];
let n = price.length;
 
console.log("Maximum profit is:", maxProfit(price, n, k));


Output

Maximum profit is: 87

Time Complexity: O(2 (n*k))
Auxiliary Space: O(1), only recursion stack space is used.

Efficient approach : Space Optimized

In this approach we use two vectors: profit and prevDiff. The profit vector stores the maximum profit using at most i transactions up to the current day, and prevDiff vector stores the maximum difference obtained by subtracting the price of the previous day.

By iterating through the prices and transactions in a bottom-up manner, we update the prevDiff and profit vectors accordingly. Finally, we return profit[k], which represents the maximum profit using at most k transactions.

Implementation Steps:

  • Define the maxProfit function with parameters price[], n, and k.
  • Create vectors profit and prevDiff with initial values.
  • Use nested loops to fill the vectors prevDiff and profit in a bottom-up manner.
  • Update prevDiff[i] and profit[i] based on the maximum values.
  • Return profit[k].

Implementation:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find out maximum profit by buying &
// selling a share at most k times given stock price
// of n days
int maxProfit(int price[], int n, int k)
{
    // vector to store results of subproblems
    // profit[i] stores maximum profit using at most
    // i transactions up to the current day
    vector<int> profit(k + 1, 0);
    vector<int> prevDiff(k + 1, INT_MIN);
 
    // fill the table in bottom-up fashion
    for (int j = 0; j < n; j++) {
        for (int i = 1; i <= k; i++) {
            prevDiff[i] = max(prevDiff[i], profit[i - 1] - price[j]);
            profit[i] = max(profit[i], price[j] + prevDiff[i]);
        }
    }
 
    return profit[k];
}
 
// Driver Code
int main()
{
    int k = 3;
    int price[] = { 12, 14, 17, 10, 14, 13, 12, 15 };
 
    int n = sizeof(price) / sizeof(price[0]);
 
    cout << "Maximum profit is: "
        << maxProfit(price, n, k);
 
    return 0;
}
 
// -- by bhardwajji


Java




import java.util.Arrays;
 
class Main {
    // Function to find out maximum profit by buying &
    // selling a share at most k times given stock price
    // of n days
    static int maxProfit(int price[], int n, int k) {
        // array to store results of subproblems
        // profit[i] stores maximum profit using at most
        // i transactions up to the current day
        int profit[] = new int[k + 1];
        int prevDiff[] = new int[k + 1];
        Arrays.fill(prevDiff, Integer.MIN_VALUE);
 
        // fill the table in bottom-up fashion
        for (int j = 0; j < n; j++) {
            for (int i = 1; i <= k; i++) {
                prevDiff[i] = Math.max(prevDiff[i], profit[i - 1] - price[j]);
                profit[i] = Math.max(profit[i], price[j] + prevDiff[i]);
            }
        }
 
        return profit[k];
    }
 
    // Driver Code
    public static void main(String[] args) {
        int k = 3;
        int price[] = { 12, 14, 17, 10, 14, 13, 12, 15 };
 
        int n = price.length;
 
        System.out.println("Maximum profit is: " + maxProfit(price, n, k));
    }
}
 
// by phasing17


Python3




# Python program of the above approach
 
# Function to find out maximum profit by buying &
# selling a share at most k times given stock price
# of n days
def max_profit(price, n, k):
    # List to store results of subproblems
    # profit[i] stores maximum profit using at most
    # i transactions up to the current day
    profit = [0] * (k + 1)
    prev_diff = [float('-inf')] * (k + 1)
 
    # Fill the table in bottom-up fashion
    for j in range(n):
        for i in range(1, k + 1):
            prev_diff[i] = max(prev_diff[i], profit[i - 1] - price[j])
            profit[i] = max(profit[i], price[j] + prev_diff[i])
 
    return profit[k]
 
# Driver Code
k = 3
price = [12, 14, 17, 10, 14, 13, 12, 15]
n = len(price)
 
print("Maximum profit is:", max_profit(price, n, k))
 
# This code is contributed by Susobhan Akhuli


C#




using System;
 
class GFG
{
    // Function to find out maximum profit by buying &
    // selling a share at most k times given stock price
    // of n days
    static int MaxProfit(int[] price, int n, int k)
    {
        // array to store results of subproblems
        // profit[i] stores maximum profit using at most
        // i transactions up to the current day
        int[] profit = new int[k + 1];
        int[] prevDiff = new int[k + 1];
        Array.Fill(prevDiff, int.MinValue);
 
        // fill the table in bottom-up fashion
        for (int j = 0; j < n; j++)
        {
            for (int i = 1; i <= k; i++)
            {
                prevDiff[i] = Math.Max(prevDiff[i],
                                       profit[i - 1] - price[j]);
                profit[i] = Math.Max(profit[i],
                                     price[j] + prevDiff[i]);
            }
        }
 
        return profit[k];
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int k = 3;
        int[] price = { 12, 14, 17, 10, 14, 13, 12, 15 };
 
        int n = price.Length;
 
        Console.WriteLine("Maximum profit is: " +
                          MaxProfit(price, n, k));
    }
}


Javascript




function maxProfit(price, n, k) {
    // vector to store results of subproblems
    // profit[i] stores maximum profit using at most
    // i transactions up to the current day
    let profit = new Array(k + 1).fill(0);
    let prevDiff = new Array(k + 1).fill(Number.MIN_SAFE_INTEGER);
 
    // fill the table in bottom-up fashion
    for (let j = 0; j < n; j++) {
        for (let i = 1; i <= k; i++) {
            prevDiff[i] = Math.max(prevDiff[i], profit[i - 1] - price[j]);
            profit[i] = Math.max(profit[i], price[j] + prevDiff[i]);
        }
    }
 
    return profit[k];
}
 
// Driver Code
let k = 3;
let price = [12, 14, 17, 10, 14, 13, 12, 15];
 
let n = price.length;
 
console.log("Maximum profit is: " + maxProfit(price, n, k));
 
 
// -- by phasing17


Output

Maximum profit is: 12

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

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments