Open in App
Not now

# Maximum Profit By Choosing A Subset Of Intervals (Using Priority-Queue)

• Difficulty Level : Medium
• 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++

 `// C++ implementation of the above approach` `#include ` `using` `namespace` `std;`   `// The main function that returns the maximum` `// possible profit from given array of` `// intervals` `int` `maximum_profit(``int` `n, vector >& intervals)` `{`   `    ``// A utility vector to include startTime,` `    ``// endTime and profit in pair` `    ``vector > > 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, vector >,` `                   ``greater > >` `        ``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 > 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 > > 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 > 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 > 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`

Output

`8`

Time complexity: O(n Log n)
Auxiliary Space: O(n)

Related Articles:

My Personal Notes arrow_drop_up
Related Articles