Open In App

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

Last Updated : 12 Aug, 2022
Improve
Improve
Like Article
Like
Save
Share
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, 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:  

  • Find the lowest price of a share before it rises followed by the highest before the prices fall again. These serve as the current buying and selling prices respectively.
  • Compare these buying and selling prices to that of the previous transaction. If the current buying price is less than that of the previous transaction, remove that transaction and consider a new transaction with the current buying price and selling price of the removed transaction to increase the profit and continue as long as the profit can be further increased with the current buying price.
  • Similarly, compare the selling prices and increase the profit if possible.
  • After traversing all the N prices, add the highest K profits. In case, the number of transactions is less than K, calculate the sum of profits of all the transactions.

Below code is the implementation of the above approach:  

C++14




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




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




# 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#




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


Javascript




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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads