Maximum Profit By Choosing A Subset Of Intervals (Using Priority-Queue)
Given a list intervals of n intervals, the ith element [s, e, p] denotes the starting point s, ending point e, and the profit p earned by choosing the ith interval. Find the maximum profit one can achieve by choosing a subset of non-overlapping intervals.
Two intervals [s1, e1, p1] and [s2, e2, p2] are said to be non-overlapping if [e1 ≤ s2] and [s1 < s2].
Examples:
Input: n = 3, intervals = {{1, 2, 4}, {1, 5, 7}, {2, 4, 4}}
Output: 8
Explanation: One can choose intervals [1, 2, 4] and [2, 4, 4] for a profit of 8.Input: n = 3, intervals = {{1, 4, 4}, {2, 3, 7}, {2, 3, 4}}
Output: 7
Explanation: One can choose interval [2, 3, 7] for a profit of 7.
Approach: The above problem can be solved with the below idea:
To find the maximum profit, sorting according to start time will lead to the maximum number of interval selections.
Follow the below steps to solve the problem:
- sort the intervals based on their start time.
- Declare a min heap priority queue.
- Iterate over the intervals and push it into the priority queue in a pair {end time, profit}.
- For every ith interval, we pop out the element from our min heap and we would consider the maximum profit if its end time is lesser or equal to the start time of the ith interval.
Below is the implementation of the above approach:
C++
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // The main function that returns the maximum // possible profit from given array of // intervals int maximum_profit( int n, vector<vector< int > >& intervals) { // A utility vector to include startTime, // endTime and profit in pair vector<pair< int , pair< int , int > > > events; for ( int i = 0; i < intervals.size(); i++) { events.push_back( { intervals[i][0], { intervals[i][1], intervals[i][2] } }); } // Min heap to store endTime and profit priority_queue<pair< int , int >, vector<pair< int , int > >, greater<pair< int , int > > > pq; // Sort the event vector based on its start // time sort(events.begin(), events.end()); // Declare a variable to store max_profit int max_profit = 0; for ( auto & e : events) { // While pq is not empty and its a // non-overlapping interval we pop it // out from the min heap and we // check for the maximum profit while (!pq.empty() && pq.top().first <= e.first) { max_profit = max(max_profit, pq.top().second); pq.pop(); } // Insert into min heap endTime and // the profit pq.push({ e.second.first, max_profit + e.second.second }); } // Check again if min heap is contain // any elements while (!pq.empty()) { // Update max_profit max_profit = max(max_profit, pq.top().second); pq.pop(); } // Maximum profit return max_profit; } // Driver code int main() { int n = 3; vector<vector< int > > intervals = { { 1, 2, 4 }, { 1, 5, 7 }, { 2, 4, 4 } }; // Function call cout << maximum_profit(n, intervals); return 0; } |
Java
import java.util.*; class Main { public static int maximumProfit( int n, int [][] intervals) { // A utility list to include startTime, endTime and // profit in pair List<Map.Entry< Integer, Map.Entry<Integer, Integer> > > events = new ArrayList<>(); for ( int i = 0 ; i < intervals.length; i++) { events.add( new AbstractMap.SimpleEntry<>( intervals[i][ 0 ], new AbstractMap.SimpleEntry<>( intervals[i][ 1 ], intervals[i][ 2 ]))); } // Min heap to store endTime and profit PriorityQueue<Map.Entry<Integer, Integer> > pq = new PriorityQueue<>( (a, b) -> a.getKey() - b.getKey()); // Sort the event list based on its start time events.sort((a, b) -> a.getKey() - b.getKey()); // Declare a variable to store max_profit int maxProfit = 0 ; for (Map.Entry<Integer, Map.Entry<Integer, Integer> > e : events) { // While pq is not empty and its a // non-overlapping interval we pop it out from // the min heap and we check for the maximum // profit while (!pq.isEmpty() && pq.peek().getKey() <= e.getKey()) { maxProfit = Math.max(maxProfit, pq.poll().getValue()); } // Insert into min heap endTime and the profit pq.offer( new AbstractMap.SimpleEntry<>( e.getValue().getKey(), maxProfit + e.getValue().getValue())); } // Check again if min heap is contain any elements while (!pq.isEmpty()) { // Update max_profit maxProfit = Math.max(maxProfit, pq.poll().getValue()); } // Maximum profit return maxProfit; } public static void main(String[] args) { int n = 3 ; int [][] intervals = { { 1 , 2 , 4 }, { 1 , 5 , 7 }, { 2 , 4 , 4 } }; // Function call System.out.println(maximumProfit(n, intervals)); } } |
Python3
#Python code for the above approach import heapq # The main function that returns the maximum # possible profit from given array of # intervals def maximum_profit(n, intervals): # A utility vector to include startTime, # endTime and profit in pair events = [] for i in range ( len (intervals)): events.append((intervals[i][ 0 ], (intervals[i][ 1 ], intervals[i][ 2 ]))) # Min heap to store endTime and profit pq = [] # Sort the event vector based on its start # time events.sort() # Declare a variable to store max_profit max_profit = 0 for e in events: # While pq is not empty and its a # non-overlapping interval we pop it # out from the min heap and we # check for the maximum profit while pq and pq[ 0 ][ 0 ] < = e[ 0 ]: max_profit = max (max_profit, pq[ 0 ][ 1 ]) heapq.heappop(pq) # Insert into min heap endTime and # the profit heapq.heappush(pq, (e[ 1 ][ 0 ], max_profit + e[ 1 ][ 1 ])) # Check again if min heap is contain # any elements while pq: # Update max_profit max_profit = max (max_profit, pq[ 0 ][ 1 ]) heapq.heappop(pq) # Maximum profit return max_profit # Driver code if __name__ = = '__main__' : n = 3 intervals = [[ 1 , 2 , 4 ], [ 1 , 5 , 7 ], [ 2 , 4 , 4 ]] # Function call print (maximum_profit(n, intervals)) #This code is contributed by Potta Lokesh |
C#
// C# implementation of the above approach using System; using System.Collections.Generic; class Program { // The main function that returns the maximum // possible profit from given array of // intervals static int MaximumProfit( int n, int [][] intervals) { // A utility list to include startTime, // endTime and profit in pair List<( int start, int end, int profit)> events = new List<( int start, int end, int profit)>(); for ( int i = 0; i < intervals.Length; i++) { events.Add((intervals[i][0], intervals[i][1], intervals[i][2])); } // Sort the event list based on its start time events.Sort((a, b) => a.start - b.start); // Declare a variable to store max_profit int maxProfit = 0; // Min heap to store endTime and profit List<( int end, int profit)> pq = new List<( int end, int profit)>(); foreach ( var e in events) { // While pq is not empty and its a // non-overlapping interval we pop it // out from the min heap and we // check for the maximum profit while (pq.Count > 0 && pq[0].end <= e.start) { maxProfit = Math.Max(maxProfit, pq[0].profit); pq.RemoveAt(0); } // Insert into min heap endTime and // the profit pq.Add((end: e.end, profit: maxProfit + e.profit)); } // Check again if min heap is contain // any elements while (pq.Count > 0) { // Update max_profit maxProfit = Math.Max(maxProfit, pq[0].profit); pq.RemoveAt(0); } // Maximum profit return maxProfit; } // Driver code static void Main( string [] args) { int n = 3; int [][] intervals = new int [][] { new int [] { 1, 2, 4 }, new int [] { 1, 5, 7 }, new int [] { 2, 4, 4 } }; // Function call Console.WriteLine(MaximumProfit(n, intervals)); } } // This code is contributed by rutikbhosale |
Javascript
// JavaScript implementation of the above approach // The main function that returns the maximum // possible profit from given array of // intervals function maximumProfit(n, intervals) { // A utility array to include startTime, // endTime and profit in pair let events = [] for (let i = 0; i < intervals.length; i++) { events.push({ start: intervals[i][0], end: intervals[i][1], profit: intervals[i][2] }); } // Sort the event array based on its start time events.sort((a, b) => a.start - b.start); // Declare a variable to store max_profit let maxProfit = 0; // Min heap to store endTime and profit let pq = [] for (let e of events) { // While pq is not empty and its a // non-overlapping interval we pop it // out from the min heap and we // check for the maximum profit while (pq.length > 0 && pq[0].end <= e.start) { maxProfit = Math.max(maxProfit, pq[0].profit); pq.shift(); } // Insert into min heap endTime and // the profit pq.push({ end: e.end, profit: maxProfit + e.profit }); } // Check again if min heap is contain // any elements while (pq.length > 0) { // Update max_profit maxProfit = Math.max(maxProfit, pq[0].profit); pq.shift(); } // Maximum profit return maxProfit; } // Driver code let n = 3; let intervals = [ [1, 2, 4], [1, 5, 7], [2, 4, 4] ]; // Function call console.log(maximumProfit(n, intervals)); //code by ksam24000 |
8
Time complexity: O(n Log n)
Auxiliary Space: O(n)
Related Articles:
Please Login to comment...