Given an array interval[] , where each element represents the following three values
startTime– the time when the interval beginsendTime– the time when the interval endsvalue– the value associated with this interval
Find the maximum sum of values by selecting at most two intervals that do not overlap.
Example:
Input: interval[] = [[1, 3, 2], [4, 5, 2], [2, 4, 3]]
Output: 4
Explanation: Select interval 1 and 2 (as third interval is overlapping). Therefore, maximum value is 2 + 2 = 4.
Input: interval[] = [[1, 3, 2], [4, 5, 2], [1, 5, 5]]
Output: 5
Explanation: As intervals 1 and 2 are non-overlapping but their value will be 2 + 2 = 4. So, instead of 1 and 2, only 3 can be selected with a value of 5.
Table of Content
[Naive Approach] - O(n2) Time and O(1) Space
For each interval (or pair of intervals), we calculate the sum of their values only if they do not overlap and keep track of the maximum sum found so far. We also consider the case where a single interval alone provides the maximum value.
[Expected Approach]Using Priority Queue - O(n x logn) Time and O(n) Space
This problem can be solved with the help of a priority queue. To solve this problem, follow the below steps:
- Sort the given array interval w.r.t. startTime. If startTime of two intervals are the same then sort it on the basis of endTime.
- Store the pair of {endTime, value} in the priority queue ordered on the basis of endTime.
- Traverse the given array and calculate the maximum value for all events whose endTime is smaller than the startTime of the present interval and store it in variable max.
- Now, update the ans, after each traversal as, ans= Math.max(ans, max + interval[i][2]).
- Return ans as the final answer to this problem.
Below is the implementation of the above approach
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int maxTwoIntervals(vector<vector<int> >& interval)
{
// Sorting the given array
// on the basis of startTime
sort(interval.begin(), interval.end(),
[](vector<int>& a, vector<int>& b) {
return (a[0] == b[0]) ? a[1] < b[1]
: a[0] < b[0];
});
priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;
int ma = 0;
int ans = 0;
for (auto e : interval) {
while (!pq.empty()) {
// If endTime from priority
// queue is greater
// than startTime of
// traversing interval
// then break the loop
if (pq.top()[0] >= e[0])
break;
vector<int> qu = pq.top();
pq.pop();
// Updating max variable
ma = max(ma, qu[1]);
}
// Update maximum answer with
// non-overlapping intervals
ans = max(ans, ma + e[2]);
pq.push({ e[1], e[2] });
}
return ans;
}
int main()
{
vector<vector<int>> interval
= { { 1, 3, 2 }, { 4, 5, 2 }, { 1, 5, 5 } };
int maxValue = maxTwoIntervals(interval);
cout << maxValue;
return 0;
}
import java.util.Arrays;
import java.util.PriorityQueue;
class GFG {
public static int maxTwoIntervals(int[][] interval)
{
// Sorting the given array
// on the basis of startTime
Arrays.sort(interval,
(a, b)
-> (a[0] == b[0]) ? a[1] - b[1]
: a[0] - b[0]);
PriorityQueue<int[]> pq
= new PriorityQueue<>((a, b) -> a[0] - b[0]);
int max = 0;
int ans = 0;
for (int[] e : interval) {
while (!pq.isEmpty()) {
// If endTime from priority
// queue is greater
// than startTime of
// traversing interval
// then break the loop
if (pq.peek()[0] >= e[0])
break;
int[] qu = pq.remove();
// Updating max variable
max = Math.max(max, qu[1]);
}
// Update maximum answer with
// non-overlapping intervals
ans = Math.max(ans, max + e[2]);
pq.add(new int[] { e[1], e[2] });
}
return ans;
}
public static void main(String[] args)
{
int[][] interval
= { { 1, 3, 2 }, { 4, 5, 2 }, { 1, 5, 5 } };
int maxValue = maxTwoIntervals(interval);
System.out.println(maxValue);
}
}
from queue import PriorityQueue
def maxTwoIntervals(interval):
# Sorting the given array
# on the basis of startTime
interval.sort()
pq = PriorityQueue()
ma = 0;
ans = 0
# Traversing the given array
for e in interval:
while not pq.empty():
# If endTime from priority
# queue is greater
# than startTime of
# traversing interval
# then break the loop
if (pq.queue[0][0] >= e[0]):
break;
qu = pq.get();
# Updating max variable
ma = max(ma, qu[1]);
# Update maximum answer with
# non-overlapping intervals
ans = max(ans, ma + e[2]);
pq.put([ e[1], e[2] ]);
return ans;
if __name__=='__main__':
interval = [ [ 1, 3, 2 ], [ 4, 5, 2 ], [ 1, 5, 5 ] ];
maxValue = maxTwoIntervals(interval);
print(maxValue);
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
public static int maxTwoIntervals(int[][] interval)
{
// Sorting the given array
// on the basis of startTime
var sorted = interval.OrderBy(a => a[0]).ThenBy(a => a[1]);
interval = sorted.ToArray();
SortedSet<int[]> pq = new SortedSet<int[]>(Comparer<int[]>.Create((a, b) =>
a[0] == b[0] ? a[1].CompareTo(b[1]) : a[0].CompareTo(b[0])));
int max = 0;
int ans = 0;
// Traversing the given array
foreach (int[] e in interval) {
while (pq.Count > 0) {
// If endTime from priority queue is greater
// than startTime of traversing
// interval then break the loop
if (pq.First()[0] >= e[0])
break;
int[] qu = pq.First();
pq.Remove(qu);
// Updating max variable
max = Math.Max(max, qu[1]);
}
// Updating ans variable
ans = Math.Max(ans, max + e[2]);
pq.Add(new int[] { e[1], e[2] });
}
return ans;
}
public static void Main(string[] args)
{
int[][] interval = new int[][] {
new int[] { 1, 3, 2 },
new int[] { 4, 5, 2 },
new int[] { 1, 5, 5 }
};
int maxValue = maxTwoIntervals(interval);
Console.WriteLine(maxValue);
}
}
function maxTwoIntervals(interval) {
// Sorting the given array
// on the basis of startTime
interval.sort((a, b) => {
if (a[0] === b[0]) {
return a[1] - b[1];
}
return a[0] - b[0];
});
let pq = [];
let ma = 0;
let ans = 0;
for (let e of interval) {
while (pq.length > 0) {
// If endTime from priority
// queue is greater
// than startTime of
// traversing interval
// then break the loop
if (pq[0][0] >= e[0])
break;
let qu = pq.shift();
// Updating max variable
ma = Math.max(ma, qu[1]);
}
// Update maximum answer with
//non-overlapping intervals
ans = Math.max(ans, ma + e[2]);
pq.unshift([e[1], e[2]]);
pq.sort((a, b) => b[0] - a[0]);
}
return ans;
}
let interval = [[1, 3, 2], [4, 5, 2], [1, 5, 5]];
let maxValue = maxTwoIntervals(interval);
console.log(maxValue);
Output
5