An interval is represented as a combination of start time and end time. Given a set of intervals, check if any two intervals intersect.
Examples:
Input: arr[] = {{1, 3}, {5, 7}, {2, 4}, {6, 8}}
Output: true
The intervals {1, 3} and {2, 4} overlap
Input: arr[] = {{1, 3}, {7, 9}, {4, 6}, {10, 13}}
Output: false
No pair of intervals overlap.
Expected time complexity is O(nLogn) where n is number of intervals.
We strongly recommend to minimize your browser and try this yourself first.
A Simple Solution is to consider every pair of intervals and check if the pair intersects or not. The time complexity of this solution is O(n2)
Method 1
A better solution is to Use Sorting. Following is complete algorithm.
1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time.
2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap. This step takes O(n) time.
So overall time complexity of the algorithm is O(nLogn) + O(n) which is O(nLogn).
Below is the implementation of above idea.
C++
#include <algorithm>
#include <iostream>
using namespace std;
struct Interval {
int start;
int end;
};
bool compareInterval(Interval i1, Interval i2)
{
return (i1.start < i2.start) ? true : false ;
}
bool isIntersect(Interval arr[], int n)
{
sort(arr, arr + n , compareInterval);
for ( int i = 1; i < n; i++)
if (arr[i - 1].end > arr[i].start)
return true ;
return false ;
}
int main()
{
Interval arr1[] = { { 1, 3 }, { 7, 9 }, { 4, 6 }, { 10, 13 } };
int n1 = sizeof (arr1) / sizeof (arr1[0]);
isIntersect(arr1, n1) ? cout << "Yes\n" : cout << "No\n" ;
Interval arr2[] = { { 6, 8 }, { 1, 3 }, { 2, 4 }, { 4, 7 } };
int n2 = sizeof (arr2) / sizeof (arr2[0]);
isIntersect(arr2, n2) ? cout << "Yes\n" : cout << "No\n" ;
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static class Interval
{
int start;
int end;
public Interval( int start, int end)
{
super ();
this .start = start;
this .end = end;
}
};
static boolean isIntersect(Interval arr[], int n)
{
Arrays.sort(arr, (i1, i2) -> {
return i1.start - i2.start;
});
for ( int i = 1 ; i < n; i++)
if (arr[i - 1 ].end > arr[i].start)
return true ;
return false ;
}
public static void main(String[] args)
{
Interval arr1[] = { new Interval( 1 , 3 ),
new Interval( 7 , 9 ),
new Interval( 4 , 6 ),
new Interval( 10 , 13 ) };
int n1 = arr1.length;
if (isIntersect(arr1, n1))
System.out.print( "Yes\n" );
else
System.out.print( "No\n" );
Interval arr2[] = { new Interval( 6 , 8 ),
new Interval( 1 , 3 ),
new Interval( 2 , 4 ),
new Interval( 4 , 7 ) };
int n2 = arr2.length;
if (isIntersect(arr2, n2))
System.out.print( "Yes\n" );
else
System.out.print( "No\n" );
}
}
|
Python3
class Interval:
def __init__( self , start, end):
self .start = start
self .end = end
def isIntersect(arr, n):
arr.sort(key = lambda x: x.start)
for i in range ( 1 , n):
if (arr[i - 1 ].end > arr[i].start):
return True
return False
arr1 = [Interval( 1 , 3 ), Interval( 7 , 9 ), Interval( 4 , 6 ), Interval( 10 , 13 )]
n1 = len (arr1)
if (isIntersect(arr1, n1)):
print ( "Yes" )
else :
print ( "No" )
arr2 = [Interval( 6 , 8 ), Interval( 1 , 3 ), Interval( 2 , 4 ), Interval( 4 , 7 )]
n2 = len (arr2)
if (isIntersect(arr2, n2)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Linq;
class GFG {
class Interval {
public int start;
public int end;
public Interval( int start, int end)
{
this .start = start;
this .end = end;
}
}
static bool IsIntersect(Interval[] arr, int n)
{
Array.Sort(arr, (i1, i2) => i1.start.CompareTo(i2.start));
for ( int i = 1; i < n; i++) {
if (arr[i - 1].end > arr[i].start) {
return true ;
}
}
return false ;
}
static void Main( string [] args)
{
Interval[] arr1
= { new Interval(1, 3), new Interval(7, 9),
new Interval(4, 6), new Interval(10, 13) };
int n1 = arr1.Length;
if (IsIntersect(arr1, n1)) {
Console.WriteLine( "Yes" );
}
else {
Console.WriteLine( "No" );
}
Interval[] arr2
= { new Interval(6, 8), new Interval(1, 3),
new Interval(2, 4), new Interval(4, 7) };
int n2 = arr2.Length;
if (IsIntersect(arr2, n2)) {
Console.WriteLine( "Yes" );
}
else {
Console.WriteLine( "No" );
}
}
}
|
Javascript
<script>
class Interval
{
constructor(start,end)
{
this .start = start;
this .end = end;
}
}
function isIntersect(arr,n)
{
arr.sort( function (i1, i2){
return i1.start - i2.start;
});
for (let i = 1; i < n; i++)
if (arr[i - 1].end > arr[i].start)
return true ;
return false ;
}
let arr1=[ new Interval(1, 3),
new Interval(7, 9),
new Interval(4, 6),
new Interval(10, 13) ];
let n1 = arr1.length;
if (isIntersect(arr1, n1))
document.write( "Yes<br>" );
else
document.write( "No<br>" );
let arr2 = [ new Interval(6, 8),
new Interval(1, 3),
new Interval(2, 4),
new Interval(4, 7) ];
let n2 = arr2.length;
if (isIntersect(arr2, n2))
document.write( "Yes<br>" );
else
document.write( "No<br>" );
</script>
|
Output:
No
Yes
Time Complexity: O(nlogn)
Auxiliary Space: O(1)
Method 2: This approach is suggested by Anjali Agarwal. Following are the steps:
1. Find the overall maximum element. Let it be max_ele
2. Initialize an array of size max_ele with 0.
3. For every interval [start, end], increment the value at index start, i.e. arr[start]++ and decrement the value at index (end + 1), i.e. arr[end + 1]- -.
4. Compute the prefix sum of this array (arr[]).
5. Every index, i of this prefix sum array will tell how many times i has occurred in all the intervals taken together. If this value is greater than 1, then it occurs in 2 or more intervals.
6. So, simply initialize the result variable as false and while traversing the prefix sum array, change the result variable to true whenever the value at that index is greater than 1.
Below is the implementation of this (Method 2) approach.
C++
#include <algorithm>
#include <iostream>
using namespace std;
struct Interval {
int start;
int end;
};
bool isIntersect(Interval arr[], int n)
{
int max_ele = 0;
for ( int i = 0; i < n; i++) {
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
int aux[max_ele + 1] = { 0 };
for ( int i = 0; i < n; i++) {
int x = arr[i].start;
int y = arr[i].end;
aux[x]++, aux[y + 1]--;
}
for ( int i = 1; i <= max_ele; i++) {
aux[i] += aux[i - 1];
if (aux[i] > 1)
return true ;
}
return false ;
}
int main()
{
Interval arr1[] = { { 1, 3 }, { 7, 9 }, { 4, 6 }, { 10, 13 } };
int n1 = sizeof (arr1) / sizeof (arr1[0]);
isIntersect(arr1, n1) ? cout << "Yes\n" : cout << "No\n" ;
Interval arr2[] = { { 6, 8 }, { 1, 3 }, { 2, 4 }, { 4, 7 } };
int n2 = sizeof (arr2) / sizeof (arr2[0]);
isIntersect(arr2, n2) ? cout << "Yes\n" : cout << "No\n" ;
return 0;
}
|
Java
class GFG
{
static class Interval
{
int start;
int end;
public Interval( int start, int end)
{
super ();
this .start = start;
this .end = end;
}
};
static boolean isIntersect(Interval arr[], int n)
{
int max_ele = 0 ;
for ( int i = 0 ; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
int []aux = new int [max_ele + 1 ];
for ( int i = 0 ; i < n; i++)
{
int x = arr[i].start;
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for ( int i = 1 ; i <= max_ele; i++)
{
aux[i] += aux[i - 1 ];
if (aux[i] > 1 )
return true ;
}
return false ;
}
public static void main(String[] args)
{
Interval arr1[] = { new Interval( 1 , 3 ), new Interval( 7 , 9 ),
new Interval( 4 , 6 ), new Interval( 10 , 13 ) };
int n1 = arr1.length;
if (isIntersect(arr1, n1))
System.out.print( "Yes\n" );
else
System.out.print( "No\n" );
Interval arr2[] = { new Interval( 6 , 8 ), new Interval( 1 , 3 ),
new Interval( 2 , 4 ), new Interval( 4 , 7 ) };
int n2 = arr2.length;
if (isIntersect(arr2, n2))
System.out.print( "Yes\n" );
else
System.out.print( "No\n" );
}
}
|
Python3
class Interval:
def __init__( self , start, end):
self .start = start
self .end = end
def is_intersect(arr, n):
max_ele = 0
for i in range (n):
if max_ele < arr[i].end:
max_ele = arr[i].end
aux = [ 0 ] * (max_ele + 1 )
for i in range (max_ele + 1 ):
aux[i] = 0
for i in range (n):
x = arr[i].start
y = arr[i].end
aux[x] + = 1
aux[y] - = 1
for i in range ( 1 , max_ele + 1 ):
aux[i] + = aux[i - 1 ]
if aux[i] > 1 :
return True
return False
arr1 = [Interval( 1 , 3 ), Interval( 7 , 9 ), Interval( 4 , 6 ), Interval( 10 , 13 )]
n1 = len (arr1)
if is_intersect(arr1, n1):
print ( "Yes" )
else :
print ( "No" )
arr2 = [Interval( 6 , 8 ), Interval( 1 , 3 ), Interval( 2 , 4 ), Interval( 4 , 7 )]
n2 = len (arr2)
if is_intersect(arr2, n2):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG
{
class Interval
{
public int start;
public int end;
public Interval( int start, int end)
{
this .start = start;
this .end = end;
}
};
static bool isIntersect(Interval []arr, int n)
{
int max_ele = 0;
for ( int i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
int []aux = new int [max_ele + 1];
for ( int i = 0; i < n; i++)
{
int x = arr[i].start;
int y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for ( int i = 1; i <= max_ele; i++)
{
aux[i] += aux[i - 1];
if (aux[i] > 1)
return true ;
}
return false ;
}
public static void Main(String[] args)
{
Interval []arr1 = { new Interval(1, 3),
new Interval(7, 9),
new Interval(4, 6),
new Interval(10, 13) };
int n1 = arr1.Length;
if (isIntersect(arr1, n1))
Console.Write( "Yes\n" );
else
Console.Write( "No\n" );
Interval []arr2 = { new Interval(6, 8),
new Interval(1, 3),
new Interval(2, 4),
new Interval(4, 7) };
int n2 = arr2.Length;
if (isIntersect(arr2, n2))
Console.Write( "Yes\n" );
else
Console.Write( "No\n" );
}
}
|
Javascript
<script>
class Interval
{
constructor(start, end)
{
this .start = start;
this .end = end;
}
}
function isIntersect(arr, n)
{
let max_ele = 0;
for (let i = 0; i < n; i++)
{
if (max_ele < arr[i].end)
max_ele = arr[i].end;
}
let aux = new Array(max_ele + 1);
for (let i=0;i<(max_ele + 1);i++)
{
aux[i]=0;
}
for (let i = 0; i < n; i++)
{
let x = arr[i].start;
let y = arr[i].end;
aux[x]++;
aux[y ]--;
}
for (let i = 1; i <= max_ele; i++)
{
aux[i] += aux[i - 1];
if (aux[i] > 1)
return true ;
}
return false ;
}
let arr1 = [ new Interval(1, 3), new Interval(7, 9),
new Interval(4, 6), new Interval(10, 13)];
let n1 = arr1.length;
if (isIntersect(arr1, n1))
document.write( "Yes<br>" );
else
document.write( "No<br>" );
let arr2 = [ new Interval(6, 8), new Interval(1, 3),
new Interval(2, 4), new Interval(4, 7) ];
let n2 = arr2.length;
if (isIntersect(arr2, n2))
document.write( "Yes<br>" );
else
document.write( "No<br>" );
</script>
|
Output:
No
Yes
Time Complexity : O(max_ele + n)
Auxiliary Space: O(max_ele)
Note: This method is more efficient than Method 1 if there are more number of intervals and at the same time maximum value among all intervals should be low, since time complexity is directly proportional to O(max_ele).
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above