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:
- Sort the segments in increasing order of their starting points. In the case of a pair having equal starting points, sort in decreasing order of ending points.
- Now, traverse the array and maintain the maximum ending point obtained so and compare it with that of the current segment.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Store ranges and their // corresponding array indices vector<pair<pair< int , int >, int > > tup;
// Function to find a pair of intersecting ranges void findIntersectingRange( int N, int ranges[][2])
{ // Stores ending point
// of every range
int curr;
// Stores the maximum
// ending point obtained
int currPos;
// Iterate from 0 to N - 1
for ( int i = 0; i < N; i++) {
int x, y;
// Starting point of
// the current range
x = ranges[i][0];
// End point of
// the current range
y = ranges[i][1];
// Push pairs into tup
tup.push_back({ { x, y }, i + 1 });
}
// Sort the tup vector
sort(tup.begin(), tup.end());
curr = tup[0].first.second;
currPos = tup[0].second;
// Iterate over the ranges
for ( int i = 1; i < N; i++) {
int Q = tup[i - 1].first.first;
int R = tup[i].first.first;
// If starting points are equal
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;
// Print the indices of the
// intersecting ranges
if (T <= curr) {
cout << tup[i].second
<< ' ' << currPos;
return ;
}
else {
curr = T;
currPos = tup[i].second;
}
}
// If no such pair of segments exist
cout << "-1 -1" ;
} // Driver Code int main()
{ // Given N
int N = 5;
// Given 2d ranges[][] array
int ranges[][2] = {
{ 1, 5 }, { 2, 10 },
{ 3, 10 }, { 2, 2 },
{ 2, 15 }};
// Function call
findIntersectingRange(N, ranges);
} |
// Java program for the above approach import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class GFG{
// Store ranges and their // corresponding array indices static ArrayList< int []> tup = new ArrayList<>();
// Function to find a pair of intersecting ranges static void findIntersectingRange( int N, int ranges[][])
{ // Stores ending point
// of every range
int curr;
// Stores the maximum
// ending point obtained
int currPos;
// Iterate from 0 to N - 1
for ( int i = 0 ; i < N; i++)
{
int x, y;
// Starting point of
// the current range
x = ranges[i][ 0 ];
// End point of
// the current range
y = ranges[i][ 1 ];
// Push pairs into tup
int [] arr = { x, y, i + 1 };
tup.add(arr);
}
// Sort the tup vector
// sort(tup.begin(), tup.end());
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 ];
// Iterate over the ranges
for ( int i = 1 ; i < N; i++)
{
int Q = tup.get(i - 1 )[ 0 ];
int R = tup.get(i)[ 0 ];
// If starting points are equal
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 ];
// Print the indices of the
// intersecting ranges
if (T <= curr)
{
System.out.print(tup.get(i)[ 2 ] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup.get(i)[ 2 ];
}
}
// If no such pair of segments exist
System.out.print( "-1 -1" );
} // Driver Code public static void main(String[] args)
{ // Given N
int N = 5 ;
// Given 2d ranges[][] array
int ranges[][] = { { 1 , 5 }, { 2 , 10 },
{ 3 , 10 }, { 2 , 2 },
{ 2 , 15 } };
// Function call
findIntersectingRange(N, ranges);
} } // This code is contributed by sanjeev2552 |
# Python3 program for the above approach # Store ranges and their # corresponding array indices # Function to find a pair of intersecting ranges def findIntersectingRange(tup, N, ranges):
# Stores ending point
# of every range
curr = 0
# Stores the maximum
# ending point obtained
currPos = 0
# Iterate from 0 to N - 1
for i in range (N):
# Starting point of
# the current range
x = ranges[i][ 0 ]
# End point of
# the current range
y = ranges[i][ 1 ]
# Push pairs into tup
tup.append([ [ x, y ], i + 1 ])
# Sort the tup vector
tup = sorted (tup)
curr = tup[ 0 ][ 0 ][ 1 ]
currPos = tup[ 0 ][ 1 ]
# Iterate over the ranges
for i in range ( 1 , N):
Q = tup[i - 1 ][ 0 ][ 0 ]
R = tup[i][ 0 ][ 0 ]
#If starting points are equal
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 ]
# Print the indices of the
# intersecting ranges
if (T < = curr):
print (tup[i][ 1 ], currPos)
return
else :
curr = T
currPos = tup[i][ 1 ]
# If no such pair of segments exist
print ( "-1 -1" )
# Driver Code if __name__ = = '__main__' :
# Given N
N = 5
# Given 2d ranges[][] array
ranges = [[ 1 , 5 ], [ 2 , 10 ],
[ 3 , 10 ], [ 2 , 2 ],
[ 2 , 15 ]]
# Function call
findIntersectingRange([], N, ranges)
# This code is contributed by mohit kumar 29
|
// C# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
class GFG{
// Store ranges and their
// corresponding array indices
static List< int []> tup = new List< int []>();
// Function to find a pair of intersecting ranges
static void findIntersectingRange( int N, int [][] ranges)
{
// Stores ending point
// of every range
int curr;
// Stores the maximum
// ending point obtained
int currPos;
// Iterate from 0 to N - 1
for ( int i = 0; i < N; i++)
{
int x, y;
// Starting point of
// the current range
x = ranges[i][0];
// End point of
// the current range
y = ranges[i][1];
// Push pairs into tup
int [] arr = { x, y, i + 1 };
tup.Add(arr);
}
// Sort the tup vector
// sort(tup.begin(), tup.end());
tup = tup.OrderBy(a => a[0]).ThenBy(a => a[1]).ThenBy(a => a[2]).ToList();
curr = tup[0][1];
currPos = tup[0][2];
// Iterate over the ranges
for ( int i = 1; i < N; i++)
{
int Q = tup[i - 1][0];
int R = tup[i][0];
// If starting points are equal
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];
// Print the indices of the
// intersecting ranges
if (T <= curr)
{
Console.Write(tup[i][2] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup[i][2];
}
}
// If no such pair of segments exist
Console.Write( "-1 -1" );
}
// Driver Code
public static void Main( string [] args)
{
// Given N
int N = 5;
// Given 2d ranges[][] array
int [][] ranges = { new int [] { 1, 5 }, new int [] { 2, 10 },
new int [] { 3, 10 }, new int [] { 2, 2 },
new int [] { 2, 15 } };
// Function call
findIntersectingRange(N, ranges);
}
} // This code is contributed by phasing17 |
<script> // JavaScript program for the above approach // Store ranges and their // corresponding array indices let tup = []; // Function to find a pair of intersecting ranges function findIntersectingRange(N,ranges)
{ // Stores ending point
// of every range
let curr;
// Stores the maximum
// ending point obtained
let currPos;
// Iterate from 0 to N - 1
for (let i = 0; i < N; i++)
{
let x, y;
// Starting point of
// the current range
x = ranges[i][0];
// End point of
// the current range
y = ranges[i][1];
// Push pairs into tup
let arr = [ x, y, i + 1 ];
tup.push(arr);
}
// Sort the tup vector
// sort(tup.begin(), tup.end());
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];
// Iterate over the ranges
for (let i = 1; i < N; i++)
{
let Q = tup[i - 1][0];
let R = tup[i][0];
// If starting points are equal
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];
// Print the indices of the
// intersecting ranges
if (T <= curr)
{
document.write(tup[i][2] + " " +
currPos);
return ;
}
else
{
curr = T;
currPos = tup[i][2];
}
}
// If no such pair of segments exist
document.write( "-1 -1" );
} // Driver Code let N = 5; // Given 2d ranges[][] array let ranges = [[ 1, 5 ], [ 2, 10 ], [ 3, 10 ], [ 2, 2 ], [ 2, 15 ]]; // Function call findIntersectingRange(N, ranges); // This code is contributed by patel2127 </script> |
4 1
Time Complexity: O(N LogN)
Auxiliary Space: O(N)