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> |
Â
Â
3 6
Â
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!