Open In App

Find the segment that overlaps with maximum number of segments

Last Updated : 14 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D array segments[][] where each segment is of the form [L, R] representing (X, Y) co-ordinates, the task is to find a segment that overlaps with maximum number of segments.

Examples:

Input: segments[][] = {{1, 4}, {2, 3}, {3, 6}}
Output: {3, 6}
Explanation: Every segment overlaps with all other segments. Therefore, print any one of them.

Input: segments[][] = {{1, 2}, {3, 8}, {4, 5}, {6, 7}, {9, 10}}
Output: {3, 8}
Explanation: The segment {3, 8} overlaps {4, 5} and {6, 7}.

Approach: Follow the steps below to solve the problem:

  • It is clear that in a segment [currL, currR], all the ‘R’ values of the remaining segments which are less than ‘currL’ and all the ‘L’ values of the remaining segments which are greater than ‘currR’ will not be counted to the answer.
  • Store all the ‘R’ values in an array and perform a binary search to find all the ‘R’ values less than ‘currL’ and similarly do this to find all the ‘L’ values greater than ‘currR’.
  • Traverse the array and update the segment coordinates with the maximum intersection at each iteration.
  • Print the segment with the maximum intersection.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the segment which
// overlaps with maximum number of segments
void maxIntersection(int segments[][2], int N)
{
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    vector<int> rvalues(N), lvalues(N);
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i) {
 
        lvalues[i] = segments[i][0];
        rvalues[i] = segments[i][1];
    }
 
    // Co-ordinate compression
    sort(lvalues.begin(), lvalues.end());
    sort(rvalues.begin(), rvalues.end());
 
    // Stores the required segment
    pair<int, int> answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
 
    for (int i = 0; i < N; ++i) {
 
        // Find number of 'R' coordinates
        // which are less than the 'L'
        // value of the current segment
        int lesser
            = lower_bound(rvalues.begin(), rvalues.end(),
                          segments[i][0])
              - rvalues.begin();
 
        // Find number of 'L' coordinates
        // which are greater than the 'R'
        // value of the current segment
        int greater = max(
            0, N
                   - (int)(upper_bound(lvalues.begin(),
                                       lvalues.end(),
                                       segments[i][1])
                           - lvalues.begin()));
 
        // Segments excluding 'lesser' and
        // 'greater' gives the number of
        // intersections
        if ((N - lesser - greater) >= numIntersections) {
            answer = { segments[i][0], segments[i][1] };
 
            // Update the current maximum
            numIntersections = (N - lesser - greater);
        }
    }
 
    // Print segment coordinates
    cout << answer.first << " " << answer.second;
}
 
// Driver Code
int main()
{
    // Given segments
    int segments[][2] = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = sizeof(segments) / sizeof(segments[0]);
 
    maxIntersection(segments, N);
}


Java




// Java program for the above approach
import java.util.*;
class GFG
{
 
// Function to find the segment which
// overlaps with maximum number of segments
static void maxIntersection(int segments[][], int N)
{
   
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    int []rvalues = new int[N];
    int []lvalues = new int[N];
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i)
    {
 
        lvalues[i] = segments[i][0];
        rvalues[i] = segments[i][1];
    }
 
    // Co-ordinate compression
    Arrays.sort(lvalues);
    Arrays.sort(rvalues);
 
    // Stores the required segment
    int []answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
    for (int i = 0; i < N; ++i)
    {
 
        // Find number of 'R' coordinates
        // which are less than the 'L'
        // value of the current segment
        int lesser
            = lower_bound(rvalues, 0,
                          segments.length,
                          segments[i][0]);
 
        // Find number of 'L' coordinates
        // which are greater than the 'R'
        // value of the current segment
        int greater = Math.max(
            0, N-(upper_bound(lvalues, 0,
                              segments.length,
                              segments[i][1])));
 
        // Segments excluding 'lesser' and
        // 'greater' gives the number of
        // intersections
        if ((N - lesser - greater) >= numIntersections) {
            answer = new int[]{ segments[i][0], segments[i][1] };
 
            // Update the current maximum
            numIntersections = (N - lesser - greater);
        }
    }
 
    // Print segment coordinates
    System.out.print(answer[0]+ " " +  answer[1]);
}
static int lower_bound(int[] a, int low, int high, int element){
    while(low < high){
        int middle = low + (high - low)/2;
        if(element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
 
 
static int upper_bound(int[] a, int low, int high, int element){
    while(low < high){
        int middle = low + (high - low)/2;
        if(a[middle] > element)
            high = middle;
        else
            low = middle + 1;
    }
    return low;
}
// Driver Code
public static void main(String[] args)
{
    // Given segments
    int segments[][] = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = segments.length;
 
    maxIntersection(segments, N);
}
}
// This code is contributed by 29AjayKumar


Python3




# Python program for the above approach
 
# Function to find the segment which
# overlaps with maximum number of segments
from bisect import bisect_left
from bisect import bisect_right
 
def maxIntersection(segments, N):
    # 'L' & 'R' co-ordinates of all
    # segments are stored in lvalues & rvalues
    rvalues = []
    lvalues = []
 
    # Assign co-ordinates
    for i in range(N):
        lvalues.append(segments[i][0])
        rvalues.append(segments[i][1])
 
    # Co-ordinate compression
    lvalues.sort()
    rvalues.sort()
 
    # Stores the required segment
    answer = [-1, -1]
 
    # Stores the current maximum
    # number of intersections
    numIntersections = 0
 
    for i in range(N):
 
        # Find number of 'R' coordinates
        # which are less than the 'L'
        # value of the current segment
        lesser = bisect_left(rvalues, segments[i][0], 0, len(segments))
 
        # Find number of 'L' coordinates
        # which are greater than the 'R'
        # value of the current segment
        greater = max(
            0, N - (bisect_right(lvalues, segments[i][1], 0, len(segments))))
 
        # Segments excluding 'lesser' and
        # 'greater' gives the number of
        # intersections
        if ((N - lesser - greater) >= numIntersections):
            answer = [segments[i][0], segments[i][1]]
 
            # Update the current maximum
            numIntersections = (N - lesser - greater)
 
    # Print segment coordinates
    print(answer[0], answer[1])
 
 
# Driver Code
# Given segments
segments = [[1, 4], [2, 3], [3, 6]]
 
# Size of segments array
N = len(segments)
 
maxIntersection(segments, N)
 
# The code is contributed by Gautam goel (gautamgoel962)


C#




// C# program for the above approach
using System;
public class GFG
{
 
  // Function to find the segment which
  // overlaps with maximum number of segments
  static void maxIntersection(int [,]segments, int N)
  {
 
    // 'L' & 'R' co-ordinates of all
    // segments are stored in lvalues & rvalues
    int []rvalues = new int[N];
    int []lvalues = new int[N];
 
    // Assign co-ordinates
    for (int i = 0; i < N; ++i)
    {
      lvalues[i] = segments[i,0];
      rvalues[i] = segments[i,1];
    }
 
    // Co-ordinate compression
    Array.Sort(lvalues);
    Array.Sort(rvalues);
 
    // Stores the required segment
    int []answer = { -1, -1 };
 
    // Stores the current maximum
    // number of intersections
    int numIntersections = 0;
    for (int i = 0; i < N; ++i)
    {
 
      // Find number of 'R' coordinates
      // which are less than the 'L'
      // value of the current segment
      int lesser
        = lower_bound(rvalues, 0,
                      segments.GetLength(0),
                      segments[i,0]);
 
      // Find number of 'L' coordinates
      // which are greater than the 'R'
      // value of the current segment
      int greater = Math.Max(
        0, N-(upper_bound(lvalues, 0,
                          segments.GetLength(0),
                          segments[i,1])));
 
      // Segments excluding 'lesser' and
      // 'greater' gives the number of
      // intersections
      if ((N - lesser - greater) >= numIntersections) {
        answer = new int[]{ segments[i,0], segments[i,1] };
 
        // Update the current maximum
        numIntersections = (N - lesser - greater);
      }
    }
 
    // Print segment coordinates
    Console.Write(answer[0]+ " " +  answer[1]);
  }
  static int lower_bound(int[] a, int low,
                         int high, int element)
  {
    while(low < high)
    {
      int middle = low + (high - low)/2;
      if(element > a[middle])
        low = middle + 1;
      else
        high = middle;
    }
    return low;
  }
 
  static int upper_bound(int[] a, int low,
                         int high, int element)
  {
    while(low < high)
    {
      int middle = low + (high - low)/2;
      if(a[middle] > element)
        high = middle;
      else
        low = middle + 1;
    }
    return low;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
 
    // Given segments
    int [,]segments = { { 1, 4 }, { 2, 3 }, { 3, 6 } };
 
    // Size of segments array
    int N = segments.GetLength(0);
    maxIntersection(segments, N);
  }
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
 
// JavaScript program for the above approach
 
 
    function lower_bound(a , low , high , element) {
        while (low < high) {
            var middle = low + (high - low) / 2;
            if (element > a[middle])
                low = middle + 1;
            else
                high = middle;
        }
        return low;
    }
 
    function upper_bound(a , low , high , element) {
        while (low < high) {
            var middle = low + (high - low) / 2;
            if (a[middle] > element)
                high = middle;
            else
                low = middle + 1;
        }
        return low;
    }
     
    // Function to find the segment which
    // overlaps with maximum number of segments
    function maxIntersection(segments , N) {
 
        // 'L' & 'R' co-ordinates of all
        // segments are stored in lvalues & rvalues
        let rvalues = Array(N).fill(0);
        let lvalues = Array(N).fill(0);
 
        // Assign co-ordinates
        for (i = 0; i < N; ++i) {
 
            lvalues[i] = segments[i][0];
            rvalues[i] = segments[i][1];
        }
 
        // Co-ordinate compression
        lvalues.sort((a,b)=>a-b);
        rvalues.sort((a,b)=>a-b);
 
        // Stores the required segment
        let answer = [ -1, -1 ];
 
        // Stores the current maximum
        // number of intersections
        var numIntersections = 0;
        for (var i = 0; i < N; ++i) {
 
            // Find number of 'R' coordinates
            // which are less than the 'L'
            // value of the current segment
            var lesser = lower_bound(rvalues, 0,
            segments.length, segments[i][0]);
 
            // Find number of 'L' coordinates
            // which are greater than the 'R'
            // value of the current segment
            var greater = Math.max(0, N - (upper_bound(lvalues,
            0, segments.length, segments[i][1])));
 
            // Segments excluding 'lesser' and
            // 'greater' gives the number of
            // intersections
            if ((N - lesser - greater) >= numIntersections) {
                answer =   [ segments[i][0], segments[i][1] ];
 
                // Update the current maximum
                numIntersections = (N - lesser - greater);
            }
        }
 
        // Print segment coordinates
        document.write(answer[0] + " " + answer[1]);
    }
 
 
    // Driver Code
     
        // Given segments
        var segments = [ [ 1, 4 ], [ 2, 3 ], [ 3, 6 ] ];
 
        // Size of segments array
        var N = segments.length;
 
        maxIntersection(segments, N);
 
// This code contributed by umadevi9616
 
</script>


 
 

Output: 

3 6

 

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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads