Open In App

Print a pair of indices of an overlapping interval from given array

Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D array arr[][] of size N, with each row representing intervals of the form {X, Y} ( 1-based indexing ), the task to find a pair of indices of overlapping intervals. If no such pair exists, then print -1 -1.

Examples: 

Input: N = 5, arr[][] = {{1, 5}, {2, 10}, {3, 10}, {2, 2}, {2, 15}}
Output: 4 1
Explanation: The range at position 4 i.e., (2, 2) lies inside the range at position 1 i.e., (1, 5).

Input: N = 4, arr[][] = {{2, 10}, {1, 9}, {1, 8}, {1, 7}}
Output: -1 -1

Naive Approach: The simplest approach is to check each pair of intervals if one of them lies inside the other one or not. If no such interval is found print -1 -1, otherwise, print the index of the found intervals.
Time Complexity: O(N2) where N is the given integer.
Auxiliary Space: O(N)

Efficient Approach: The idea is to sort the given set of intervals based on the left part of each interval. Follow the steps below to solve the problem:

  1. First, sort the segments by their left border in increasing order by storing the index of each interval.
  2. Then, initialize the variables curr and currPos with the left part of the first interval in the sorted array and its index respectively.
  3. Now, traverse the sorted intervals from i = 0 to N – 1.
  4. If the left parts of any two adjacent intervals are equal, then print their indices as one of them got to lie inside another.
  5. If the right part of the current interval is greater than curr, then set curr equal to that right part and currPos equal to the index of that interval in the original array. Otherwise, print the index of the current interval and the index stored in the currPos variable.
  6. After traversing, if no such interval is found, print -1 -1.

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Pair of two integers
// of the form {X, Y}
typedef pair<int, int> ii;
 
// Pair of pairs and integers
typedef pair<ii, int> iii;
 
// FUnction to find a pair of indices of
// the overlapping interval in the array
ii segment_overlapping(int N,
                       vector<vector<int> > arr)
{
 
    // Store intervals {X, Y} along
    // with their indices
    vector<iii> tup;
 
    // Traverse the given intervals
    for (int i = 0; i < N; i++) {
 
        int x, y;
        x = arr[i][0];
        y = arr[i][1];
 
        // Store intervals and their indices
        tup.push_back(iii(ii(x, y), i + 1));
    }
 
    // Sort the intervals
    sort(tup.begin(), tup.end());
 
    // Stores Y of the first interval
    int curr = tup[0].first.second;
 
    // Stores index of first interval
    int currPos = tup[0].second;
 
    // Traverse the sorted intervals
    for (int i = 1; i < N; i++) {
 
        // Stores X value of previous interval
        int Q = tup[i - 1].first.first;
 
        // Stores X value of current interval
        int R = tup[i].first.first;
 
        // If Q and R equal
        if (Q == R) {
 
            // If Y value of immediate previous
            // interval is less than Y value of
            // current interval
            if (tup[i - 1].first.second
                < tup[i].first.second) {
 
                // Stores index of immediate
                // previous interval
                int X = tup[i - 1].second;
 
                // Stores index of current
                // interval
                int Y = tup[i].second;
 
                return { X, Y };
            }
 
            else {
 
                // Stores index of current
                // interval
                int X = tup[i].second;
 
                // Stores index of immediate
                // previous interval
                int Y = tup[i - 1].second;
 
                return { X, Y };
            }
        }
 
        // Stores Y value of current interval
        int T = tup[i].first.second;
 
        // T is less than or equal to curr
        if (T <= curr)
            return { tup[i].second, currPos };
 
        else {
 
            // Update curr
            curr = T;
 
            // Update currPos
            currPos = tup[i].second;
        }
    }
 
    // No answer exists
    return { -1, -1 };
}
 
// Driver Code
int main()
 
{
 
    // Given intervals
    vector<vector<int> > arr = { { 1, 5 }, { 2, 10 },
                                 { 3, 10 }, { 2, 2 },
                                 { 2, 15 } };
 
    // Size of intervals
    int N = arr.size();
 
    // Find answer
    ii ans = segment_overlapping(N, arr);
 
    // Print answer
    cout << ans.first << " " << ans.second;
}


Java




// Java program for above approach
import java.util.*;
import java.lang.*;
 
// Pair of two integers
// of the form {X, Y}
class pair1
{
  int first, second;
  pair1(int first, int second)
  {
    this.first = first;
    this.second = second;
  }
}
 
// Pair of pairs and integers
class pair2
{
  int first, second, index;
  pair2(int first, int second, int index)
  {
    this.first = first;
    this.second = second;
    this.index = index;
  }
}
class GFG
{
 
  // Function to find a pair of indices of
  // the overlapping interval in the array
  static pair1 segment_overlapping(int N,
                                   int[][] arr)
  {
 
    // Store intervals {X, Y} along
    // with their indices
    ArrayList<pair2> tup=new ArrayList<>();
 
    // Traverse the given intervals
    for (int i = 0; i < N; i++)
    {
 
      int x, y;
      x = arr[i][0];
      y = arr[i][1];
 
      // Store intervals and their indices
      tup.add(new pair2(x, y, i + 1));
    }
 
    // Sort the intervals
    Collections.sort(tup, (a, b)->(a.first != b.first) ?
                     a.first - b.first:a.second - b.second);
 
    // Stores Y of the first interval
    int curr = tup.get(0).second;
 
    // Stores index of first interval
    int currPos = tup.get(0).index;
 
    // Traverse the sorted intervals
    for (int i = 1; i < N; i++)
    {
 
      // Stores X value of previous interval
      int Q = tup.get(i - 1).first;
 
      // Stores X value of current interval
      int R = tup.get(i).first;
 
      // If Q and R equal
      if (Q == R)
      {
 
        // If Y value of immediate previous
        // interval is less than Y value of
        // current interval
        if (tup.get(i - 1).second
            < tup.get(i).second)
        {
 
          // Stores index of immediate
          // previous interval
          int X = tup.get(i - 1).index;
 
          // Stores index of current
          // interval
          int Y = tup.get(i).index;
 
          return new pair1( X, Y );
        }
 
        else {
 
          // Stores index of current
          // interval
          int X = tup.get(i).index;
 
          // Stores index of immediate
          // previous interval
          int Y = tup.get(i - 1).index;
 
          return new pair1( X, Y );
        }
      }
 
      // Stores Y value of current interval
      int T = tup.get(i).second;
 
      // T is less than or equal to curr
      if (T <= curr)
        return new pair1( tup.get(i).index, currPos );
 
      else
      {
 
        // Update curr
        curr = T;
 
        // Update currPos
        currPos = tup.get(i).index;
      }
    }
 
    // No answer exists
    return new pair1(-1, -1 );
  }
  // Driver function
  public static void main (String[] args)
  {
 
    // Given intervals
    int[][] arr = { { 1, 5 }, { 2, 10 },
                   { 3, 10 }, { 2, 2 },
                   { 2, 15 } };
 
    // Size of intervals
    int N = arr.length;
 
    // Find answer
    pair1 ans = segment_overlapping(N, arr);
 
    // Print answer
    System.out.print(ans.first+" "+ans.second);
  }
}
 
// This code is contributed by offbeat


Python3




# Python3 program for the above approach
 
# FUnction to find a pair of indices of
# the overlapping interval in the array
def segment_overlapping(N, arr):
 
    # Store intervals {X, Y} along
    # with their indices
    tup = []
 
    # Traverse the given intervals
    for i in range(N):
        x = arr[i][0]
        y = arr[i][1]
 
        # Store intervals and their indices
        tup.append([x, y, i + 1])
 
    # Sort the intervals
    tup = sorted(tup)
 
    # Stores Y of the first interval
    curr = tup[0][1]
 
    # Stores index of first interval
    currPos = tup[0][2]
 
    # Traverse the sorted intervals
    for i in range(1, N):
 
        # Stores X value of previous interval
        Q = tup[i - 1][0]
 
        # Stores X value of current interval
        R = tup[i][0]
 
        # If Q and R equal
        if (Q == R):
 
            # If Y value of immediate previous
            # interval is less than Y value of
            # current interval
            if (tup[i - 1][1] < tup[i][1]):
 
                # Stores index of immediate
                # previous interval
                X = tup[i - 1][2]
 
                # Stores index of current
                # interval
                Y = tup[i][2]
                return [X, Y]
            else:
 
                # Stores index of current
                # interval
                X = tup[i][2]
 
                # Stores index of immediate
                # previous interval
                Y = tup[i - 1][2]
                return { X, Y }
 
        # Stores Y value of current interval
        T = tup[i][1]
 
        # T is less than or equal to curr
        if (T <= curr):
            return [tup[i][2], currPos]
 
        else:
 
            # Update curr
            curr = T
 
            # Update currPos
            currPos = tup[i][2]
     
    # No answer exists
    return [ -1, -1 ]
 
# Driver Code
if __name__ == '__main__':
 
    # Given intervals
    arr = [ [ 1, 5 ], [ 2, 10 ], [ 3, 10 ], [ 2, 2 ], [2, 15 ] ]
 
    # Size of intervals
    N = len(arr)
 
    # Find answer
    ans = segment_overlapping(N, arr)
 
    # Print answer
    print(ans[0], ans[1])
 
    # This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
   
// Function to find a pair of indices of
// the overlapping interval in the array
static void segment_overlapping(int N, int[,] arr)
{
 
    // Store intervals {X, Y} along
    // with their indices
    List<Tuple<Tuple<int, int>,
                     int>> tup = new List<Tuple<Tuple<int, int>,
                                                      int>>();
     
    // Traverse the given intervals
    for(int i = 0; i < N; i++)
    {
         
        int x, y;
        x = arr[i, 0];
        y = arr[i, 1];
         
        // Store intervals and their indices
        tup.Add(new Tuple<Tuple<int, int>, int>(
                      new Tuple<int, int>(x, y), i + 1));
    }
     
    // Sort the intervals
    tup.Sort();
     
    // Stores Y of the first interval
    int curr = tup[0].Item1.Item2;
     
    // Stores index of first interval
    int currPos = tup[0].Item2;
     
    // Traverse the sorted intervals
    for(int i = 1; i < N; i++)
    {
     
        // Stores X value of previous interval
        int Q = tup[i - 1].Item1.Item1;
         
        // Stores X value of current interval
        int R = tup[i].Item1.Item1;
         
        // If Q and R equal
        if (Q == R)
        {
             
            // If Y value of immediate previous
            // interval is less than Y value of
            // current interval
            if (tup[i - 1].Item1.Item2 <
                tup[i].Item1.Item2)
            {
             
                // Stores index of immediate
                // previous interval
                int X = tup[i - 1].Item2;
                 
                // Stores index of current
                // interval
                int Y = tup[i].Item2;
                 
                Console.WriteLine(X + " " + Y);
                 
                return;
            }
             
            else
            {
                 
                // Stores index of current
                // interval
                int X = tup[i].Item2;
                 
                // Stores index of immediate
                // previous interval
                int Y = tup[i - 1].Item2;
                 
                Console.WriteLine(X + " " + Y);
                 
                return;
            }
        }
     
        // Stores Y value of current interval
        int T = tup[i].Item1.Item2;
         
        // T is less than or equal to curr
        if (T <= curr)
        {
            Console.Write(tup[i].Item2 + " " + currPos);
            return;
        }
        else
        {
             
            // Update curr
            curr = T;
             
            // Update currPos
            currPos = tup[i].Item2;
        }
    }
     
    // No answer exists
    Console.Write("-1 -1");
}
 
// Driver code
static public void Main()
{
     
    // Given intervals
    int[,] arr = { { 1, 5 }, { 2, 10 },
                   { 3, 10 }, { 2, 2 },
                   { 2, 15 } };
     
    // Size of intervals
    int N = arr.Length / 2;
     
    segment_overlapping(N, arr);
}
}
 
// This code is contributed by Dharanendra L V.


Javascript




<script>
 
// Javascript program for the above approach
 
// FUnction to find a pair of indices of
// the overlapping interval in the array
function segment_overlapping(N, arr)
{
 
    // Store intervals {X, Y} along
    // with their indices
    var tup = [];
 
    // Traverse the given intervals
    for (var i = 0; i < N; i++) {
 
        var x, y;
        x = arr[i][0];
        y = arr[i][1];
 
        // Store intervals and their indices
        tup.push([[x, y], i + 1]);
    }
 
    // Sort the intervals
    tup.sort((a,b) =>
    {
       if(a[0][0] == b[0][0])
       {
           return a[0][1] - b[0][1];
       }
        
       var tmp = (a[0][0] - b[0][0]);
       console.log(tmp);
 
       return (a[0][0] - b[0][0])
    });
 
    // Stores Y of the first interval
    var curr = tup[0][0][1];
 
    // Stores index of first interval
    var currPos = tup[0][1];
 
    // Traverse the sorted intervals
    for (var i = 1; i < N; i++) {
 
        // Stores X value of previous interval
        var Q = tup[i - 1][0][0];
 
        // Stores X value of current interval
        var R = tup[i][0][0];
 
        // If Q and R equal
        if (Q == R) {
 
            // If Y value of immediate previous
            // interval is less than Y value of
            // current interval
            if (tup[i - 1][0][1]
                < tup[i][0][1]) {
 
                // Stores index of immediate
                // previous interval
                var X = tup[i - 1][1];
 
                // Stores index of current
                // interval
                var Y = tup[i][1];
 
                return [X, Y];
            }
 
            else {
 
                // Stores index of current
                // interval
                var X = tup[i][1];
 
                // Stores index of immediate
                // previous interval
                var Y = tup[i - 1][1];
 
                return [X, Y];
            }
        }
 
        // Stores Y value of current interval
        var T = tup[i][0][1];
 
        // T is less than or equal to curr
        if (T <= curr)
            return [tup[i][1], currPos];
 
        else {
 
            // Update curr
            curr = T;
 
            // Update currPos
            currPos = tup[i][1];
        }
    }
 
    // No answer exists
    return [-1, -1];
}
 
// Driver Code
// Given intervals
var arr = [ [ 1, 5 ], [ 2, 10 ],
                             [ 3, 10 ], [ 2, 2 ],
                             [ 2, 15 ] ];
// Size of intervals
var N = arr.length;
 
// Find answer
var ans = segment_overlapping(N, arr);
 
// Print answer
document.write( ans[0] + " " + ans[1]);
 
// This code is contributed by importantly.
</script>


Output: 

4 1

 

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)



Last Updated : 01 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads