Find a pair of intersecting ranges from a given array
Last Updated :
19 Dec, 2022
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++
// 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
// 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
# 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#
// 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
JavaScript
<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>
Time Complexity: O(N LogN)
Auxiliary Space: O(N)
Similar Reads
Find all the intersecting pairs from a given array Given n pairs (S[i], F[i]) where for every i, S[i]< F[i]. Two ranges are said to intersect if and only if either of them does not fully lie inside the other one that is only one point of a pair lies between the start and end of the other pair. We have to print all the intersecting ranges for each
14 min read
Find a pair of overlapping intervals from a given Set Given a 2D array arr[][] with each row of the form {l, r}, the task is to find a pair (i, j) such that the ith interval lies within the jth interval. If multiple solutions exist, then print anyone of them. Otherwise, print -1. Examples: Input: N = 5, arr[][] = { { 1, 5 }, { 2, 10 }, { 3, 10}, {2, 2}
11 min read
Find 5 non-intersecting ranges with given constraints Given Five integers A, B, C, D and E. the task is to find five non-intersecting ranges [X1, Y1], [X2, Y2], [X3, Y3], [X4, Y4], [X5, Y5] such that, the following 5 conditions hold. X1 + Y1 = min(A, B)X2 * Y2 = max(A, B)|X3 - Y3| = C?X4 / Y4? = DX5 % Y5 = E Examples: Input: A = 6, B = 36, C = 20, D =
6 min read
Find Next Optimal Range in Array Given an array ranges[][] of size N x 2, where for every i, range[i][0] is the start and range[i][1] is the end of the range. For every range, find the index of the Next Optimal Range. For a range i which ends at a point X, all the ranges that have their starting points >= X will be the Next Opti
7 min read
Count of intersecting lines formed from every possible pair of given points Given two arrays of integers, X and Y representing points in the X-Y plane. Calculate the number of intersecting pairs of line segments formed from every possible pair of coordinates. Example: Input: X = [0, 1, 0, 1], Y = [0, 1, 3, 2] Output: 14 Explanation: For simplicity let's denote A = [0, 0], B
15+ min read