Find least non-overlapping number from a given set of intervals
Last Updated :
29 Mar, 2023
Given an array interval of pairs of integers representing the starting and ending points of the interval of size N. The task is to find the smallest non-negative integer which is a non-overlapping number from the given set of intervals.
Input constraints:
Examples:
Input: interval = {{0, 4}, {6, 8}, {2, 3}, {9, 18}}
Output: 5
Explanation:
The smallest non-negative integer which is non-overlapping to all set of the intervals is 5.
Input: interval = {{0, 14}, {86, 108}, {22, 30}, {5, 17}}
Output: 18
Naive Approach:
- Create a visited array of size MAX, and for every interval mark all value true from start to end.
- Finally, iterate from 1 to MAX and find the smallest value which is not visited.
However, this approach will not work if the interval coordinates are up to 10 9.
Time Complexity: O (N 2)
Auxiliary Space: O (MAX)
Efficient Approach:
- Instead of iterating from start to end just create a visited array and for each range, mark vis[start] = 1 and vis[end+1] = -1.
- Take the prefix sum of the array.
- Then iterate over the array to find the first integer with value 0.
Here is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 5;
void find_missing(
vector<pair< int , int > > interval)
{
vector< int > vis(MAX);
for ( int i = 0; i < interval.size(); ++i) {
int start = interval[i].first;
int end = interval[i].second;
vis[start]++;
vis[end + 1]--;
}
for ( int i = 1; i < MAX; i++) {
vis[i] += vis[i - 1];
if (!vis[i]) {
cout << i << endl;
return ;
}
}
}
int main()
{
vector<pair< int , int > > interval
= { { 0, 14 }, { 86, 108 },
{ 22, 30 }, { 5, 17 } };
find_missing(interval);
return 0;
}
|
Java
import java.io.*;
public class GFG{
static int MAX = ( int ) (1e5 + 5 );
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void find_missing(
pair[] interval)
{
int [] vis = new int [MAX];
for ( int i = 0 ; i < interval.length; ++i)
{
int start = interval[i].first;
int end = interval[i].second;
vis[start]++;
vis[end + 1 ]--;
}
for ( int i = 1 ; i < MAX; i++) {
vis[i] += vis[i - 1 ];
if (vis[i]== 0 ) {
System.out.print(i + "\n" );
return ;
}
}
}
public static void main(String[] args)
{
pair []interval = { new pair( 0 , 14 ),
new pair( 86 , 108 ),
new pair( 22 , 30 ),
new pair( 5 , 17 )};
find_missing(interval);
}
}
|
Python3
MAX = int ( 1e5 + 5 )
def find_missing(interval):
vis = [ 0 ] * ( MAX )
for i in range ( len (interval)):
start = interval[i][ 0 ]
end = interval[i][ 1 ]
vis[start] + = 1
vis[end + 1 ] - = 1
for i in range ( 1 , MAX ):
vis[i] + = vis[i - 1 ]
if (vis[i] = = 0 ):
print (i)
return
interval = [ [ 0 , 14 ], [ 86 , 108 ],
[ 22 , 30 ], [ 5 , 17 ] ]
find_missing(interval)
|
C#
using System;
class GFG{
static int MAX = ( int )(1e5 + 5);
class pair
{
public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void find_missing(pair[] interval)
{
int [] vis = new int [MAX];
for ( int i = 0; i < interval.Length; ++i)
{
int start = interval[i].first;
int end = interval[i].second;
vis[start]++;
vis[end + 1]--;
}
for ( int i = 1; i < MAX; i++)
{
vis[i] += vis[i - 1];
if (vis[i] == 0)
{
Console.Write(i + "\n" );
return ;
}
}
}
public static void Main(String[] args)
{
pair []interval = { new pair(0, 14),
new pair(86, 108),
new pair(22, 30),
new pair(5, 17) };
find_missing(interval);
}
}
|
Javascript
<script>
var MAX = 100005;
function find_missing( interval)
{
var vis = Array(MAX).fill(0);
for ( var i = 0; i < interval.length; ++i) {
var start = interval[i][0];
var end = interval[i][1];
vis[start]++;
vis[end + 1]--;
}
for ( var i = 1; i < MAX; i++) {
vis[i] += vis[i - 1];
if (!vis[i]) {
document.write( i + "<br>" );
return ;
}
}
}
var interval
= [ [ 0, 14 ], [ 86, 108 ],
[ 22, 30 ], [ 5, 17 ] ];
find_missing(interval);
</script>
|
Time Complexity: O (N)
Auxiliary Space: O (MAX)
However, this approach will also not work if the interval coordinates are up to 10 9.
Efficient Approach:
- Sort the range by their start-coordinate and for each next range.
- Check if the starting point is greater than the maximum end-coordinate encountered so far, then a missing number can be found, and it will be previous_max + 1.
Illustration:
Consider the following example:
interval[][] = { { 0, 14 }, { 86, 108 }, { 22, 30 }, { 5, 17 } };
After sorting, interval[][] = { { 0, 14 }, { 5, 17 }, { 22, 30 }, { 86, 108 }};
Initial mx = 0 and after considering first interval mx = max(0, 15) = 15
Since mx = 15 and 15 > 5 so after considering second interval mx = max(15, 18) = 18
now 18 < 22 so 18 is least non-overlapping number.
Here is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void find_missing(
vector<pair< int , int > > interval)
{
sort(interval.begin(), interval.end());
int mx = 0;
for ( int i = 0; i < ( int )interval.size(); ++i) {
if (interval[i].first > mx) {
cout << mx;
return ;
}
else
mx = max(mx, interval[i].second + 1);
}
cout << mx;
}
int main()
{
vector<pair< int , int > > interval
= { { 0, 14 }, { 86, 108 },
{ 22, 30 }, { 5, 17 } };
find_missing(interval);
return 0;
}
|
Java
import java.util.*;
import java.io.*;
class GFG{
static class Pair implements Comparable<Pair>
{
int start,end;
Pair( int s, int e)
{
start = s;
end = e;
}
public int compareTo(Pair p)
{
return this .start - p.start;
}
}
static void findMissing(ArrayList<Pair> interval)
{
Collections.sort(interval);
int mx = 0 ;
for ( int i = 0 ; i < interval.size(); ++i)
{
if (interval.get(i).start > mx)
{
System.out.println(mx);
return ;
}
else
mx = Math.max(mx, interval.get(i).end + 1 );
}
System.out.println(mx);
}
public static void main(String []args)
{
ArrayList<Pair> interval = new ArrayList<>();
interval.add( new Pair( 0 , 14 ));
interval.add( new Pair( 86 , 108 ));
interval.add( new Pair( 22 , 30 ));
interval.add( new Pair( 5 , 17 ));
findMissing(interval);
}
}
|
Python3
def find_missing(interval):
interval.sort()
mx = 0
for i in range ( len (interval)):
if (interval[i][ 0 ] > mx):
print (mx)
return
else :
mx = max (mx,
interval[i][ 1 ] + 1 )
print (mx)
if __name__ = = "__main__" :
interval = [[ 0 , 14 ], [ 86 , 108 ],
[ 22 , 30 ], [ 5 , 17 ]]
find_missing(interval);
|
C#
using System;
using System.Collections.Generic;
class GFG{
class Pair : IComparable<Pair>
{
public int start,end;
public Pair( int s, int e)
{
start = s;
end = e;
}
public int CompareTo(Pair p)
{
return this .start - p.start;
}
}
static void findMissing(List<Pair> interval)
{
interval.Sort();
int mx = 0;
for ( int i = 0; i < interval.Count; ++i)
{
if (interval[i].start > mx)
{
Console.WriteLine(mx);
return ;
}
else
mx = Math.Max(mx, interval[i].end + 1);
}
Console.WriteLine(mx);
}
public static void Main(String []args)
{
List<Pair> interval = new List<Pair>();
interval.Add( new Pair(0, 14));
interval.Add( new Pair(86, 108));
interval.Add( new Pair(22, 30));
interval.Add( new Pair(5, 17));
findMissing(interval);
}
}
|
Javascript
<script>
function findMissing(interval)
{
interval.sort( function (a,b){ return a[0]-b[0];});
let mx = 0;
for (let i = 0; i < interval.length; ++i)
{
if (interval[i][0] > mx)
{
document.write(mx+ "<br>" );
return ;
}
else
mx = Math.max(mx, interval[i][1] + 1);
}
document.write(mx);
}
let interval = [[0, 14], [86, 108],
[22, 30], [5, 17]];
findMissing(interval);
</script>
|
Time Complexity: O (N * logN)
Auxiliary Space: O (1)
Another Approach:
Approach:
Sort the intervals in ascending order based on their end points. This can be done using any efficient sorting algorithm such as merge sort or quicksort.
Initialize a variable “last” to the smallest possible integer value. This variable will keep track of the end point of the last interval that was added to the output.
Iterate through each interval in the sorted list. If the start point of the current interval is greater than “last”, add the end point of the current interval to the output and update “last” to be the end point of the current interval.
Return the value of “last” as the least non-overlapping number.
C++
#include <bits/stdc++.h>
using namespace std;
struct Interval {
int start;
int end;
};
bool compare( const Interval& a, const Interval& b) {
return a.end < b.end;
}
int findLeastNonOverlappingNumber(Interval intervals[], int n) {
sort(intervals, intervals + n, compare);
int last = -2147483648;
for ( int i = 0; i < n; i++) {
if (intervals[i].start > last) {
last = intervals[i].end;
}
}
return last;
}
int main() {
Interval intervals[] = {{1, 3}, {2, 4}, {3, 6}, {5, 7}, {7, 8}};
int n = sizeof (intervals) / sizeof (intervals[0]);
int leastNonOverlappingNumber = findLeastNonOverlappingNumber(intervals, n);
cout << "The least non-overlapping number is " << leastNonOverlappingNumber << endl;
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct Interval {
int start;
int end;
};
int compare( const void * a, const void * b) {
return (( struct Interval*)a)->end - (( struct Interval*)b)->end;
}
int findLeastNonOverlappingNumber( struct Interval intervals[], int n) {
qsort (intervals, n, sizeof ( struct Interval), compare);
int last = -2147483648;
for ( int i = 0; i < n; i++) {
if (intervals[i].start > last) {
last = intervals[i].end;
}
}
return last;
}
int main() {
struct Interval intervals[] = {{1, 3}, {2, 4}, {3, 6}, {5, 7}, {7, 8}};
int n = sizeof (intervals) / sizeof (intervals[0]);
int leastNonOverlappingNumber = findLeastNonOverlappingNumber(intervals, n);
printf ( "The least non-overlapping number is %d\n" , leastNonOverlappingNumber);
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Comparator;
class Interval {
int start;
int end;
public Interval( int start, int end) {
this .start = start;
this .end = end;
}
}
public class Main {
public static int findLeastNonOverlappingNumber(Interval[] intervals) {
Arrays.sort(intervals, new Comparator<Interval>() {
@Override
public int compare(Interval a, Interval b) {
return a.end - b.end;
}
});
int last = Integer.MIN_VALUE;
for ( int i = 0 ; i < intervals.length; i++) {
if (intervals[i].start > last) {
last = intervals[i].end;
}
}
return last;
}
public static void main(String[] args) {
Interval[] intervals = { new Interval( 1 , 3 ), new Interval( 2 , 4 ), new Interval( 3 , 6 ), new Interval( 5 , 7 ), new Interval( 7 , 8 )};
int leastNonOverlappingNumber = findLeastNonOverlappingNumber(intervals);
System.out.println( "The least non-overlapping number is " + leastNonOverlappingNumber);
}
}
|
Python3
from typing import List , Tuple
class Interval:
def __init__( self , start: int , end: int ):
self .start = start
self .end = end
def findLeastNonOverlappingNumber(intervals: List [Interval]) - > int :
intervals.sort(key = lambda x: x.end)
last = float ( '-inf' )
for interval in intervals:
if interval.start > last:
last = interval.end
return last
if __name__ = = '__main__' :
intervals = [Interval( 1 , 3 ), Interval( 2 , 4 ), Interval( 3 , 6 ), Interval( 5 , 7 ), Interval( 7 , 8 )]
leastNonOverlappingNumber = findLeastNonOverlappingNumber(intervals)
print (f 'The least non-overlapping number is {leastNonOverlappingNumber}' )
|
C#
using System;
using System.Collections.Generic;
public class Interval {
public int start;
public int end;
public Interval( int start, int end)
{
this .start = start;
this .end = end;
}
}
public class Program {
public static int
findLeastNonOverlappingNumber(Interval[] intervals)
{
Array.Sort(intervals, (a, b) = > a.end - b.end);
int last = int .MinValue;
foreach (Interval interval in intervals)
{
if (interval.start > last) {
last = interval.end;
}
}
return last;
}
static void Main( string [] args)
{
Interval[] intervals
= { new Interval(1, 3), new Interval(2, 4),
new Interval(3, 6), new Interval(5, 7),
new Interval(7, 8) };
int leastNonOverlappingNumber
= findLeastNonOverlappingNumber(intervals);
Console.WriteLine(
"The least non-overlapping number is "
+ leastNonOverlappingNumber);
}
}
|
Javascript
class Interval {
constructor(start, end) {
this .start = start;
this .end = end;
}
}
function compare(a, b) {
return a.end - b.end;
}
function findLeastNonOverlappingNumber(intervals) {
const n = intervals.length;
intervals.sort(compare);
let last = -2147483648;
for (let i = 0; i < n; i++) {
if (intervals[i].start > last) {
last = intervals[i].end;
}
}
return last;
}
( function ()
{
const intervals = [ new Interval(1, 3), new Interval(2, 4), new Interval(3, 6), new Interval(5, 7), new Interval(7, 8)];
const leastNonOverlappingNumber = findLeastNonOverlappingNumber(intervals);
console.log(`The least non-overlapping number is ${leastNonOverlappingNumber}`);
})();
|
OutputThe least non-overlapping number is 7
time complexity of O(nlogn), Where n is the size of the intervals
space complexity of O(n), Where n is the size of the intervals
Share your thoughts in the comments
Please Login to comment...