Maximum Profit By Choosing A Subset Of Intervals (Using Priority-Queue)
Last Updated :
17 Feb, 2023
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++
#include <bits/stdc++.h>
using namespace std;
int maximum_profit( int n, vector<vector< int > >& intervals)
{
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] } });
}
priority_queue<pair< int , int >, vector<pair< int , int > >,
greater<pair< int , int > > >
pq;
sort(events.begin(), events.end());
int max_profit = 0;
for ( auto & e : events) {
while (!pq.empty() && pq.top().first <= e.first) {
max_profit = max(max_profit, pq.top().second);
pq.pop();
}
pq.push({ e.second.first,
max_profit + e.second.second });
}
while (!pq.empty()) {
max_profit = max(max_profit, pq.top().second);
pq.pop();
}
return max_profit;
}
int main()
{
int n = 3;
vector<vector< int > > intervals
= { { 1, 2, 4 }, { 1, 5, 7 }, { 2, 4, 4 } };
cout << maximum_profit(n, intervals);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int maximumProfit( int n,
int [][] intervals)
{
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 ])));
}
PriorityQueue<Map.Entry<Integer, Integer> > pq
= new PriorityQueue<>(
(a, b) -> a.getKey() - b.getKey());
events.sort((a, b) -> a.getKey() - b.getKey());
int maxProfit = 0 ;
for (Map.Entry<Integer,
Map.Entry<Integer, Integer> > e :
events) {
while (!pq.isEmpty()
&& pq.peek().getKey() <= e.getKey()) {
maxProfit = Math.max(maxProfit,
pq.poll().getValue());
}
pq.offer( new AbstractMap.SimpleEntry<>(
e.getValue().getKey(),
maxProfit + e.getValue().getValue()));
}
while (!pq.isEmpty()) {
maxProfit
= Math.max(maxProfit, pq.poll().getValue());
}
return maxProfit;
}
public static void main(String[] args)
{
int n = 3 ;
int [][] intervals
= { { 1 , 2 , 4 }, { 1 , 5 , 7 }, { 2 , 4 , 4 } };
System.out.println(maximumProfit(n, intervals));
}
}
|
Python3
import heapq
def maximum_profit(n, intervals):
events = []
for i in range ( len (intervals)):
events.append((intervals[i][ 0 ], (intervals[i][ 1 ], intervals[i][ 2 ])))
pq = []
events.sort()
max_profit = 0
for e in events:
while pq and pq[ 0 ][ 0 ] < = e[ 0 ]:
max_profit = max (max_profit, pq[ 0 ][ 1 ])
heapq.heappop(pq)
heapq.heappush(pq, (e[ 1 ][ 0 ], max_profit + e[ 1 ][ 1 ]))
while pq:
max_profit = max (max_profit, pq[ 0 ][ 1 ])
heapq.heappop(pq)
return max_profit
if __name__ = = '__main__' :
n = 3
intervals = [[ 1 , 2 , 4 ], [ 1 , 5 , 7 ], [ 2 , 4 , 4 ]]
print (maximum_profit(n, intervals))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int MaximumProfit( int n, int [][] intervals)
{
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]));
}
events.Sort((a, b) => a.start - b.start);
int maxProfit = 0;
List<( int end, int profit)> pq = new List<( int end, int profit)>();
foreach ( var e in events)
{
while (pq.Count > 0 && pq[0].end <= e.start)
{
maxProfit = Math.Max(maxProfit, pq[0].profit);
pq.RemoveAt(0);
}
pq.Add((end: e.end, profit: maxProfit + e.profit));
}
while (pq.Count > 0)
{
maxProfit = Math.Max(maxProfit, pq[0].profit);
pq.RemoveAt(0);
}
return maxProfit;
}
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 }
};
Console.WriteLine(MaximumProfit(n, intervals));
}
}
|
Javascript
function maximumProfit(n, intervals) {
let events = []
for (let i = 0; i < intervals.length; i++) {
events.push({
start: intervals[i][0],
end: intervals[i][1],
profit: intervals[i][2]
});
}
events.sort((a, b) => a.start - b.start);
let maxProfit = 0;
let pq = []
for (let e of events) {
while (pq.length > 0 && pq[0].end <= e.start) {
maxProfit = Math.max(maxProfit, pq[0].profit);
pq.shift();
}
pq.push({ end: e.end, profit: maxProfit + e.profit });
}
while (pq.length > 0) {
maxProfit = Math.max(maxProfit, pq[0].profit);
pq.shift();
}
return maxProfit;
}
let n = 3;
let intervals = [
[1, 2, 4],
[1, 5, 7],
[2, 4, 4]
];
console.log(maximumProfit(n, intervals));
|
Time complexity: O(n Log n)
Auxiliary Space: O(n)
Related Articles:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...