Minimum Set size for covering intervals
Last Updated :
25 Aug, 2023
Given an array arr[] consisting of N ranges of the form [L, R], the task is to determine the size of the smallest set that contains at least 2 integers within each interval.
Examples:
Input: arr[] = { {1, 3}, {2, 5}, {1, 4} }
Output: 2
Explanation: Interval [1, 3] contains the numbers 1, 2, 3.
Interval [2, 5] contains the numbers 2, 3, 4, 5.
Interval [1, 4] contains the numbers 1, 2, 3, 4.
Selecting set {2, 3} would be the smallest set covering all intervals.
Input: arr[] = { {3, 6}, {2, 4}, {0, 2}, {4, 7} }
Output: 4
Explanation: Possible Sets are
- [0, 2], [4, 5] = 5
- [1, 2], [4, 5] = 4
- [0, 2], [4, 6] = 6
- [1, 2], [4, 6] = 5
Optimum answer is 4 from 2nd set.
Approach: To solve the problem follow the below idea:
- Sort the array according to their endpoint in ascending order, AND if two intervals have the same end, sort them according to their start point in descending order.
- If there is no number in this interval being chosen before, we pick up the 2 biggest number in this interval (the biggest number have the most possibility to be used by the next interval).
- If there is one number in this interval being chosen before, we pick up the biggest number in this interval.
- If there are already two numbers in this interval being chosen before, we can skip this interval since the requirement has been fulfilled.
Below are the steps for the above approach:
- Sort the intervals vector.
- Initialize a variable say n to store the size of the input intervals vector.
- Initialize a vector res with the two rightmost points of the intervals.
- Iterate the sorted interval vector, for each interval, the start and end points are stored in the start and end variables.
- Check if the start point of the current interval is greater than the rightmost point of the res vector, that means there is no common integer between the current interval and the previous interval, hence add the two rightmost points of the current interval to the res vector.
- Check if the start point of the current interval is greater than the second last element of the res vector, that means there is only one common integer between the current interval and the previous interval, hence update the last element of the res vector with the endpoint of the current interval.
- Return the size of the res vector.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool compare(vector< int >& a, vector< int >& b)
{
if (a[1] == b[1])
return a[0] < b[0];
else
return a[1] < b[1];
}
int intersectionSizeTwo(vector<vector< int > >& intervals)
{
int n = intervals.size();
sort(intervals.begin(), intervals.end(), compare);
vector< int > res;
res.push_back(intervals[0][1] - 1);
res.push_back(intervals[0][1]);
for ( int i = 1; i < n; i++) {
int start = intervals[i][0];
int end = intervals[i][1];
if (start > res.back()) {
res.push_back(end - 1);
res.push_back(end);
}
else if (start > res[res.size() - 2]) {
res.push_back(end);
}
}
return res.size();
}
int main()
{
vector<vector< int > > range
= { { 3, 6 }, { 2, 4 }, { 0, 2 }, { 4, 7 } };
cout << intersectionSizeTwo(range) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
public static int compare(List<Integer> a,
List<Integer> b)
{
if (a.get( 1 ).equals(b.get( 1 ))) {
return a.get( 0 ).compareTo(b.get( 0 ));
}
else {
return a.get( 1 ).compareTo(b.get( 1 ));
}
}
public static int
intersectionSizeTwo(List<List<Integer> > intervals)
{
int n = intervals.size();
Collections.sort(intervals, GFG::compare);
List<Integer> res = new ArrayList<>();
res.add(intervals.get( 0 ).get( 1 ) - 1 );
res.add(intervals.get( 0 ).get( 1 ));
for ( int i = 1 ; i < n; i++) {
int start = intervals.get(i).get( 0 );
int end = intervals.get(i).get( 1 );
if (start > res.get(res.size() - 1 )) {
res.add(end - 1 );
res.add(end);
}
else if (start > res.get(res.size() - 2 )) {
res.add(end);
}
}
return res.size();
}
public static void main(String[] args)
{
List<List<Integer> > range = Arrays.asList(
Arrays.asList( 3 , 6 ), Arrays.asList( 2 , 4 ),
Arrays.asList( 0 , 2 ), Arrays.asList( 4 , 7 ));
System.out.println(intersectionSizeTwo(range));
}
}
|
Python3
def intersectionSizeTwo(intervals):
n = len (intervals)
def compare(a, b):
if a[ 1 ] = = b[ 1 ]:
return a[ 0 ] < b[ 0 ]
else :
return a[ 1 ] < b[ 1 ]
intervals.sort(key = lambda x: (x[ 1 ], x[ 0 ]))
res = [intervals[ 0 ][ 1 ] - 1 , intervals[ 0 ][ 1 ]]
for i in range ( 1 , n):
start = intervals[i][ 0 ]
end = intervals[i][ 1 ]
if start > res[ - 1 ]:
res.append(end - 1 )
res.append(end)
elif start > res[ - 2 ]:
res.append(end)
return len (res)
def main():
ranges = [[ 3 , 6 ], [ 2 , 4 ], [ 0 , 2 ], [ 4 , 7 ]]
print (intersectionSizeTwo(ranges))
main()
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
public static int Compare(List< int > a, List< int > b)
{
if (a[1] == b[1])
{
return a[0].CompareTo(b[0]);
}
else
{
return a[1].CompareTo(b[1]);
}
}
public static int IntersectionSizeTwo(List<List< int >> intervals)
{
int n = intervals.Count;
intervals.Sort(Compare);
List< int > res = new List< int >();
res.Add(intervals[0][1] - 1);
res.Add(intervals[0][1]);
for ( int i = 1; i < n; i++)
{
int start = intervals[i][0];
int end = intervals[i][1];
if (start > res[res.Count - 1])
{
res.Add(end - 1);
res.Add(end);
}
else if (start > res[res.Count - 2])
{
res.Add(end);
}
}
return res.Count;
}
public static void Main( string [] args)
{
List<List< int >> range = new List<List< int >>
{
new List< int > { 3, 6 },
new List< int > { 2, 4 },
new List< int > { 0, 2 },
new List< int > { 4, 7 }
};
Console.WriteLine(IntersectionSizeTwo(range));
}
}
|
Javascript
function compare(a, b) {
if (a[1] === b[1]) {
return a[0] - b[0];
} else {
return a[1] - b[1];
}
}
function intersectionSizeTwo(intervals) {
let n = intervals.length;
intervals.sort(compare);
let res = [];
res.push(intervals[0][1] - 1);
res.push(intervals[0][1]);
for (let i = 1; i < n; i++) {
let start = intervals[i][0];
let end = intervals[i][1];
if (start > res[res.length - 1]) {
res.push(end - 1);
res.push(end);
}
else if (start > res[res.length - 2]) {
res.push(end);
}
}
return res.length;
}
let range = [
[3, 6], [2, 4],
[0, 2], [4, 7]
];
console.log(intersectionSizeTwo(range));
|
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...