Open In App

Maximum profit by buying and selling a share at most K times | Greedy Approach

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. The task is to find out the maximum profit that a share trader could have made. 

Examples: 



Input: prices[] = {10, 22, 5, 75, 65, 80}, K = 2 
Output: 87 
Explanation: The trader performs 2 transactions, the first of which is by purchasing at price 10 and selling it at price 22 followed by a purchase and sale at price 5 and 80 respectively. Thus, the profit earned is 87.

Input: prices[] = {12, 14, 17, 10, 14, 13, 12, 15}, K = 3 
Output: 12 
Explanation: First transaction involves purchase and sell at prices 12 and 17 respectively. Second one is a purchase at price 10 and sell at 14 followed by a purchase at 12 and sell at 15. Thus, the total profit earned is 12. 



Please refer this article for Dynamic Programming Approach

Approach: This approach shows how to solve this problem using Greedy Approach:  

Below code is the implementation of the above approach:  




// C++ program to find out maximum profit by
// buying and selling a share at most k times
// given the stock price of n days
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the maximum profit
int maxProfit(int n, int k, int prices[])
{
    int ans = 0, buy = 0, sell = 0;
 
    stack<pair<int, int> > transaction;
    priority_queue<int> profits;
 
    while (sell < n) {
 
        buy = sell;
 
        // Find the farthest decreasing span
        // of prices before prices rise
        while (buy < n - 1
               && prices[buy] >= prices[buy + 1])
            buy++;
 
        sell = buy + 1;
 
        // Find the farthest increasing span
        // of prices before prices fall again
        while (sell < n
               && prices[sell] >= prices[sell - 1])
            sell++;
 
        // Check if the current buying price
        // is greater than that
        // of the previous transaction
        while (!transaction.empty()
               && prices[buy]
                      < prices[transaction.top().first]) {
            pair<int, int> p = transaction.top();
 
            // Store the profit
            profits.push(prices[p.second - 1]
                         - prices[p.first]);
 
            // Remove the previous transaction
            transaction.pop();
        }
 
        // Check if the current selling price is
        // less than that of the previous transactions
        while (!transaction.empty()
               && prices[sell - 1]
                      > prices[transaction.top().second - 1]) {
            pair<int, int> p = transaction.top();
 
            // Store the new profit
            profits.push(prices[p.second - 1]
                         - prices[buy]);
            buy = p.first;
 
            // Remove the previous transaction
            transaction.pop();
        }
 
        // Add the new transactions
        transaction.push({ buy, sell });
    }
 
    // Finally store the profits
    // of all the transactions
    while (!transaction.empty()) {
        profits.push(
            prices[transaction.top().second - 1]
            - prices[transaction.top().first]);
        transaction.pop();
    }
 
    // Add the highest K profits
    while (k && !profits.empty()) {
        ans += profits.top();
        profits.pop();
        --k;
    }
 
    // Return the maximum profit
    return ans;
}
 
// Driver code
int main()
{
    int k = 3;
    int prices[] = { 1, 12, 10, 7,
                     10, 13, 11, 10,
                     7, 6, 9 };
    int n = sizeof(prices) / sizeof(prices[0]);
 
    cout << "Maximum profit is "
         << maxProfit(n, k, prices);
 
    return 0;
}




// Java program to find out maximum profit
// by buying and selling a share at most k
// times given the stock price of n days
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to return the maximum profit
static int maxProfit(int n, int k,
                     int prices[])
{
    int ans = 0, buy = 0, sell = 0;
     
    Stack<int[]> transaction = new Stack<>();
    PriorityQueue<Integer> profits = new PriorityQueue<>();
   
    while (sell < n)
    {
        buy = sell;
         
        // Find the farthest decreasing span
        // of prices before prices rise
        while (buy < n - 1 &&
        prices[buy] >= prices[buy + 1])
            buy++;
   
        sell = buy + 1;
   
        // Find the farthest increasing span
        // of prices before prices fall again
        while (sell < n &&
        prices[sell] >= prices[sell - 1])
            sell++;
   
        // Check if the current buying price
        // is greater than that of the
        // previous transaction
        while (!transaction.isEmpty() &&
               prices[buy] <
               prices[transaction.peek()[0]])
        {
            int[] p = transaction.peek();
             
            // Store the profit
            profits.add(prices[p[1] - 1] -
                        prices[p[0]]);
             
            // Remove the previous transaction
            transaction.pop();
        }
         
        // Check if the current selling price
        // is less than that of the previous
        // transactions
        while (!transaction.isEmpty() &&
               prices[sell - 1] >
               prices[transaction.peek()[1] - 1])
        {
            int[] p = transaction.peek();
             
            // Store the new profit
            profits.add(prices[p[1] - 1] -
                        prices[buy]);
                         
            buy = p[0];
             
            // Remove the previous transaction
            transaction.pop();
        }
         
        // Add the new transactions
        transaction.push(new int[]{ buy, sell });
    }
   
    // Finally store the profits
    // of all the transactions
    while (!transaction.isEmpty())
    {
        profits.add(
            prices[transaction.peek()[1] - 1] -
            prices[transaction.peek()[0]]);
             
        transaction.pop();
    }
   
    // Add the highest K profits
    while (k > 0 && !profits.isEmpty())
    {
        ans += profits.peek();
        profits.poll();
        --k;
    }
   
    // Return the maximum profit
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int k = 3;
    int prices[] = { 1, 12, 10, 7, 10, 13,
                     11, 10, 7, 6, 9 };
    int n = prices.length;
     
    System.out.println("Maximum profit is " +
                       maxProfit(n, k, prices));
}
}
 
// This code is contributed by offbeat




# 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 return the maximum profit
def maxProfit(n, k, prices):
    ans = 0
    buy = 0
    sell = 0
    # stack
    transaction = []
    # priority queue
    profits = []
 
    while (sell < n):
        buy = sell
 
        # Find the farthest decreasing span
        # of prices before prices rise
        while (buy < n - 1 and prices[buy] >= prices[buy + 1]):
            buy += 1
 
        sell = buy + 1
 
        # Find the farthest increasing span
        # of prices before prices fall again
        while (sell < n and prices[sell] >= prices[sell - 1]):
            sell += 1
 
        # Check if the current buying price
        # is greater than that
        # of the previous transaction
        while (len(transaction) !=0 and prices[buy] < prices[transaction[len(transaction)-1][0]]):
            p = transaction[len(transaction)-1]
 
            # Store the profit
            profits.append(prices[p[1] - 1] - prices[p[0]])
 
            # Remove the previous transaction
            transaction.remove(transaction[len(transaction)-1])
 
        # Check if the current selling price is
        # less than that of the previous transactions
        profits.sort(reverse=True)
        while (len(transaction)!=0 and prices[sell - 1] > prices[transaction[len(transaction)-1][1] - 1]):
            p = transaction[len(transaction)-1]
 
            # Store the new profit
            profits.append(prices[p[1] - 1] - prices[buy])
            buy = p[0]
 
            # Remove the previous transaction
            transaction.remove(transaction[len(transaction)-1])
 
        # Add the new transactions
        transaction.append([buy, sell])
     
    profits.sort(reverse=True)
    # Finally store the profits
    # of all the transactions
    while (len(transaction) != 0):
        profits.append(prices[transaction[len(transaction)-1][1]- 1]-prices[transaction[len(transaction)-1][0]])
        transaction.remove(transaction[len(transaction)-1])
 
    profits.sort(reverse=True)
    # Add the highest K profits
    while (k!=0 and len(profits)!=0):
        ans += profits[0]
        profits.remove(profits[0])
        k -= 1
 
    # Return the maximum profit
    return ans
 
# Driver code
if __name__ == '__main__':
    k = 3
    prices = [1, 12, 10, 7,10, 13, 11, 10,7, 6, 9]
    n = len(prices)
 
    print("Maximum profit is",maxProfit(n, k, prices))
 
# This code is contributed by Surendra_Gangwar




// C# program to find out maximum profit by
// buying && selling a share at most k times
// given the stock price of n days
 
using System;
using System.Collections.Generic;
 
class GFG {
    // Function to return the maximum profit
    static int maxProfit(int n, int k, int[] prices)
    {
        int ans = 0;
        int buy = 0;
        int sell = 0;
 
        // stack
        List<int[]> transaction = new List<int[]>();
 
        // priority queue
        List<int> profits = new List<int>();
 
        while (sell < n) {
            buy = sell;
 
            // Find the farthest decreasing span
            // of prices before prices rise
            while (buy < n - 1
                   && prices[buy] >= prices[buy + 1])
                buy += 1;
 
            sell = buy + 1;
 
            // Find the farthest increasing span
            // of prices before prices fall again
            while (sell < n
                   && prices[sell] >= prices[sell - 1])
                sell += 1;
 
            // Check if the current buying price
            // is greater than that
            // of the previous transaction
            while (transaction.Count != 0
                   && prices[buy] < prices
                              [transaction[transaction.Count
                                           - 1][0]]) {
                int[] p
                    = transaction[transaction.Count - 1];
 
                // Store the profit
                profits.Add(prices[p[1] - 1]
                            - prices[p[0]]);
 
                // Remove the previous transaction
                transaction.RemoveAt(transaction.Count - 1);
            }
 
            // Check if the current selling price is
            // less than that of the previous transactions
            profits.Sort();
 
            while (transaction.Count != 0
                   && prices[sell - 1] > prices
                              [transaction[transaction.Count
                                           - 1][1]
                               - 1]) {
                int[] p
                    = transaction[transaction.Count - 1];
 
                // Store the new profit
                profits.Add(prices[p[1] - 1] - prices[buy]);
                buy = p[0];
 
                // Remove the previous transaction
                transaction.RemoveAt(transaction.Count - 1);
            }
 
            // Add the new transactions
            int[] elem = { buy, sell };
            transaction.Add(elem);
        }
 
        profits.Sort();
 
        // Finally store the profits
        // of all the transactions
        while (transaction.Count != 0) {
            profits.Add(
                prices[transaction[transaction.Count - 1][1]
                       - 1]
                - prices[transaction[transaction.Count - 1]
                                    [0]]);
            transaction.RemoveAt(transaction.Count - 1);
        }
 
        profits.Sort();
        // Add the highest K profits
        while (k != 0 && profits.Count != 0) {
            ans += profits[0];
            profits.RemoveAt(0);
            k -= 1;
        }
 
        // Return the maximum profit
        return ans;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int k = 3;
        int[] prices
            = { 1, 12, 10, 7, 10, 13, 11, 10, 7, 6, 9 };
        int n = prices.Length;
 
        Console.Write("Maximum profit is "
                      + maxProfit(n, k, prices));
    }
}
 
// This code is contributed by phasing17




<script>
 
// JavaScript program to find out maximum profit by
// buying && selling a share at most k times
// given the stock price of n days
 
// Function to return the maximum profit
function maxProfit(n, k, prices){
    let ans = 0
    let buy = 0
    let sell = 0
    // stack
    let transaction = []
    // priority queue
    let profits = []
 
    while (sell < n){
        buy = sell
 
        // Find the farthest decreasing span
        // of prices before prices rise
        while (buy < n - 1 && prices[buy] >= prices[buy + 1])
            buy += 1
 
        sell = buy + 1
 
        // Find the farthest increasing span
        // of prices before prices fall again
        while (sell < n && prices[sell] >= prices[sell - 1])
            sell += 1
 
        // Check if the current buying price
        // is greater than that
        // of the previous transaction
        while (transaction.length !=0 && prices[buy] < prices[transaction[transaction.length-1][0]]){
            p = transaction[transaction.length-1]
 
            // Store the profit
            profits.push(prices[p[1] - 1] - prices[p[0]])
 
            // Remove the previous transaction
            transaction.pop()
      }
 
        // Check if the current selling price is
        // less than that of the previous transactions
        profits.sort((a,b)=>b-a)
        while (transaction.length!=0 && prices[sell - 1] > prices[transaction[transaction.length-1][1] - 1]){
            let p = transaction[transaction.length-1]
 
            // Store the new profit
            profits.push(prices[p[1] - 1] - prices[buy])
            buy = p[0]
 
            // Remove the previous transaction
            transaction.pop()
      }
 
        // Add the new transactions
        transaction.push([buy, sell])
   }
     
    profits.sort((a,b)=>b-a)
    // Finally store the profits
    // of all the transactions
    while (transaction.length != 0){
        profits.push(prices[transaction[transaction.length-1][1]- 1]-prices[transaction[transaction.length-1][0]])
        transaction.pop()
   }
    profits.sort((a,b)=>b-a)
    // Add the highest K profits
    while (k!=0 && profits.length!=0){
        ans += profits[0]
        profits.shift()
        k -= 1
   }
 
    // Return the maximum profit
    return ans
}
 
// Driver code
let k = 3
let prices = [1, 12, 10, 7,10, 13, 11, 10,7, 6, 9]
let n = prices.length
 
document.write("Maximum profit is",maxProfit(n, k, prices),"</br>")
 
// This code is contributed by Shinjanpatra
 
</script>

Output: 
Maximum profit is 20

 

Time Complexity: O(N * log N)

Auxiliary Space: O(N)
 


Article Tags :