Find a pair of intersecting ranges from a given array
Given a 2D array ranges[][] of size N * 2, with each row representing a range of the form [L, R], the task is to find two ranges such that the first range completely lies ins the second range and print their indices. If no such pair of ranges can be obtained, print -1. If multiple such ranges exist, print any one of them.
Segment [L1, ?R1] lies within segment [L2, ?R2] if L1 ??L2 and R1?? R2.
Examples:
Input: N = 5, ranges[][] = {{1, 5}, {2, 10}, {3, 10}, {2, 2}, {2, 15}}
Output: 4 1
Explanation: Segment [2, 2] lies completely within the segment [1, 5], as 1 ? 2 and 2 ? 5.
Input: N = 4, ranges[][] = {{2, 10}, {1, 9}, {1, 8}, {1, 7}}
Output: -1
Explanation: No such pair of segments exist.
Naive Approach: The simplest approach to solve the problem is to iterate over the array and for each range, traverse over the remaining array to check if any range exists or not which lies completely inside the current range or vice versa.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to sort the array of ranges using a comparator function and check whether any segment lies inside any other segment or not. Follow the steps given below to solve this problem:
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector<pair<pair< int , int >, int > > tup;
void findIntersectingRange( int N, int ranges[][2])
{
int curr;
int currPos;
for ( int i = 0; i < N; i++) {
int x, y;
x = ranges[i][0];
y = ranges[i][1];
tup.push_back({ { x, y }, i + 1 });
}
sort(tup.begin(), tup.end());
curr = tup[0].first.second;
currPos = tup[0].second;
for ( int i = 1; i < N; i++) {
int Q = tup[i - 1].first.first;
int R = tup[i].first.first;
if (Q == R) {
if (tup[i - 1].first.second
< tup[i].first.second)
cout << tup[i - 1].second << ' '
<< tup[i].second;
else
cout << tup[i].second << ' '
<< tup[i - 1].second;
return ;
}
int T = tup[i].first.second;
if (T <= curr) {
cout << tup[i].second
<< ' ' << currPos;
return ;
}
else {
curr = T;
currPos = tup[i].second;
}
}
cout << "-1 -1" ;
}
int main()
{
int N = 5;
int ranges[][2] = {
{ 1, 5 }, { 2, 10 },
{ 3, 10 }, { 2, 2 },
{ 2, 15 }};
findIntersectingRange(N, ranges);
}
|
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class GFG{
static ArrayList< int []> tup = new ArrayList<>();
static void findIntersectingRange( int N, int ranges[][])
{
int curr;
int currPos;
for ( int i = 0 ; i < N; i++)
{
int x, y;
x = ranges[i][ 0 ];
y = ranges[i][ 1 ];
int [] arr = { x, y, i + 1 };
tup.add(arr);
}
Collections.sort(tup, new Comparator< int []>()
{
public int compare( int [] a, int [] b)
{
if (a[ 0 ] == b[ 0 ])
{
if (a[ 1 ] == b[ 1 ])
{
return a[ 2 ] - b[ 2 ];
}
else
{
return a[ 1 ] - b[ 1 ];
}
}
return a[ 0 ] - b[ 0 ];
}
});
curr = tup.get( 0 )[ 1 ];
currPos = tup.get( 0 )[ 2 ];
for ( int i = 1 ; i < N; i++)
{
int Q = tup.get(i - 1 )[ 0 ];
int R = tup.get(i)[ 0 ];
if (Q == R)
{
if (tup.get(i - 1 )[ 1 ] < tup.get(i)[ 1 ])
System.out.print(tup.get(i - 1 )[ 2 ] + " " +
tup.get(i)[ 2 ]);
else
System.out.print(tup.get(i)[ 2 ] + " " +
tup.get(i - 1 )[ 2 ]);
return ;
}
int T = tup.get(i)[ 1 ];
if (T <= curr)
{
System.out.print(tup.get(i)[ 2 ] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup.get(i)[ 2 ];
}
}
System.out.print( "-1 -1" );
}
public static void main(String[] args)
{
int N = 5 ;
int ranges[][] = { { 1 , 5 }, { 2 , 10 },
{ 3 , 10 }, { 2 , 2 },
{ 2 , 15 } };
findIntersectingRange(N, ranges);
}
}
|
Python3
def findIntersectingRange(tup, N, ranges):
curr = 0
currPos = 0
for i in range (N):
x = ranges[i][ 0 ]
y = ranges[i][ 1 ]
tup.append([ [ x, y ], i + 1 ])
tup = sorted (tup)
curr = tup[ 0 ][ 0 ][ 1 ]
currPos = tup[ 0 ][ 1 ]
for i in range ( 1 , N):
Q = tup[i - 1 ][ 0 ][ 0 ]
R = tup[i][ 0 ][ 0 ]
if (Q = = R):
if (tup[i - 1 ][ 0 ][ 1 ] < tup[i][ 0 ][ 1 ]):
print (tup[i - 1 ][ 1 ], tup[i][ 1 ])
else :
print (tup[i][ 1 ], tup[i - 1 ][ 1 ])
return
T = tup[i][ 0 ][ 1 ]
if (T < = curr):
print (tup[i][ 1 ], currPos)
return
else :
curr = T
currPos = tup[i][ 1 ]
print ( "-1 -1" )
if __name__ = = '__main__' :
N = 5
ranges = [[ 1 , 5 ], [ 2 , 10 ],
[ 3 , 10 ], [ 2 , 2 ],
[ 2 , 15 ]]
findIntersectingRange([], N, ranges)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG{
static List< int []> tup = new List< int []>();
static void findIntersectingRange( int N, int [][] ranges)
{
int curr;
int currPos;
for ( int i = 0; i < N; i++)
{
int x, y;
x = ranges[i][0];
y = ranges[i][1];
int [] arr = { x, y, i + 1 };
tup.Add(arr);
}
tup = tup.OrderBy(a => a[0]).ThenBy(a => a[1]).ThenBy(a => a[2]).ToList();
curr = tup[0][1];
currPos = tup[0][2];
for ( int i = 1; i < N; i++)
{
int Q = tup[i - 1][0];
int R = tup[i][0];
if (Q == R)
{
if (tup[i - 1][1] < tup[i][1])
Console.Write(tup[i - 1][2] + " " +
tup[i][2]);
else
Console.Write(tup[i][2] + " " +
tup[i - 1][2]);
return ;
}
int T = tup[i][1];
if (T <= curr)
{
Console.Write(tup[i][2] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup[i][2];
}
}
Console.Write( "-1 -1" );
}
public static void Main( string [] args)
{
int N = 5;
int [][] ranges = { new int [] { 1, 5 }, new int [] { 2, 10 },
new int [] { 3, 10 }, new int [] { 2, 2 },
new int [] { 2, 15 } };
findIntersectingRange(N, ranges);
}
}
|
Javascript
<script>
let tup = [];
function findIntersectingRange(N,ranges)
{
let curr;
let currPos;
for (let i = 0; i < N; i++)
{
let x, y;
x = ranges[i][0];
y = ranges[i][1];
let arr = [ x, y, i + 1 ];
tup.push(arr);
}
tup.sort( function (a,b)
{
if (a[0] == b[0])
{
if (a[1] == b[1])
{
return a[2] - b[2];
}
else
{
return a[1] - b[1];
}
}
return a[0] - b[0];
});
curr = tup[0][1];
currPos = tup[0][2];
for (let i = 1; i < N; i++)
{
let Q = tup[i - 1][0];
let R = tup[i][0];
if (Q == R)
{
if (tup[i - 1][1] < tup[i][1])
document.write(tup[i - 1][2] + " " +
tup[i][2]);
else
document.write(tup[i][2] + " " +
tup[i - 1][2]);
return ;
}
let T = tup[i][1];
if (T <= curr)
{
document.write(tup[i][2] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup[i][2];
}
}
document.write( "-1 -1" );
}
let N = 5;
let ranges = [[ 1, 5 ], [ 2, 10 ],
[ 3, 10 ], [ 2, 2 ],
[ 2, 15 ]];
findIntersectingRange(N, ranges);
</script>
|
Time Complexity: O(N LogN)
Auxiliary Space: O(N)
Last Updated :
19 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...