Skip to content
Related Articles

Related Articles

Improve Article

Maximum number of intersections possible for any of the N given segments

  • Last Updated : 22 Jun, 2021

Given an array arr[] consisting of N pairs of type {L, R}, each representing a segment on the X-axis, the task is to find the maximum number of intersections a segment has with other segments.

Examples:

Input: arr[] = {{1, 6}, {5, 5}, {2, 3}}
Output: 2
Explanation:
Below are the count of each segment that overlaps with the other segments:

  1. The first segment [1, 6] intersects with 2 segments [5, 5] and [2, 3].
  2. The second segment [5, 5] intersects with 1 segment [1, 6].
  3. The third segment [2, 3] intersects with 1 segment [1, 6].

Therefore, the maximum number of intersections among all the segment is 2.

Input: arr[][] = {{4, 8}, {3, 6}, {7, 11}, {9, 10}}
Output: 2



Naive Approach: The simplest approach to solve the given problem is to iterate over all segments and for each segment count the number of intersections by checking it with all other segments and then print the maximum among all the count of intersections obtained.

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized based on the following observations:

  • The above approach can be optimized by traversing each segment and calculating the number of segments that do not intersect the current segment using Binary Search and from that find the number of segments that intersect with the current segment
  • Suppose [L, R] is the current segment and [P, Q] is another segment then, the segment [L, R] does not intersect with segment [P, Q] if Q < L or P > R.
  • Suppose X is the number of the segments not intersecting with segment [L, R] then, the count of segments that intersects segment [L, R] = (N – 1 – X).

Follow the steps below to solve the problem:

  • Store all the left points of segments in an array say L[] and all the right points of the segments in the array say R[].
  • Sort both the arrays L[] and R[] in ascending order.
  • Initialize a variable, say count as 0 to store the count of the maximum intersection a segment has.
  • Traverse the array arr[] and perform the following steps:
    • Calculate the number of segments left to the current segment {arr[i][0], arr[i][1]} using lower_bound() and store it in a variable say cnt.
    • Calculate the number of segments right to the current segment {arr[i][0], arr[i][1]} using upper_bound() and increment the count of cnt by it.
    • Update the value of count as the maximum of count and (N – cnt – 1).
  • After completing the above steps, print the value of the count as the result.

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 maximum number
// of intersections one segment has with
// all the other given segments
int maximumIntersections(int arr[][2],
                         int N)
{
    // Stores the resultant maximum count
    int count = 0;
 
    // Stores the starting and the
    // ending points
    int L[N], R[N];
 
    for (int i = 0; i < N; i++) {
        L[i] = arr[i][0];
        R[i] = arr[i][1];
    }
 
    // Sort arrays points in the
    // ascending order
    sort(L, L + N);
    sort(R, R + N);
 
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
        int l = arr[i][0];
        int r = arr[i][1];
 
        // Find the count of segments
        // on left of ith segment
        int x = lower_bound(R, R + N, l) - R;
 
        // Find the count of segments
        // on right of ith segment
        int y = N - (upper_bound(L, L + N, r) - L);
 
        // Find the total segments not
        // intersecting with the current
        // segment
        int cnt = x + y;
 
        // Store the count of segments
        // that intersect with the
        // ith segment
        cnt = N - cnt - 1;
 
        // Update the value of count
        count = max(count, cnt);
    }
 
    // Return  the resultant count
    return count;
}
 
// Driver Code
int main()
{
    int arr[][2] = { { 1, 6 }, { 5, 5 }, { 2, 3 } };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << maximumIntersections(arr, N);
 
    return 0;
}

Java




// java program for the above approach
import java.util.*;
 
class GFG
{static int lower_bound(int[] a, int low, int high, long element)
    {
        while(low < high)
        {
            int middle = low + (high - low) / 2;
            if(element > a[middle])
                low = middle + 1;
            else
                high = middle;
        }
        return low;
    }
static int maximumIntersections(int [][]arr,
                         int N)
{
    // Stores the resultant maximum count
    int count = 0;
   
    // Stores the starting and the
    // ending points
    int[] L = new int[N];
    int[] R = new int[N];
    for (int i = 0; i < N; i++) {
        L[i] = arr[i][0];
        R[i] = arr[i][1];
    }
   
    // Sort arrays points in the
    // ascending order
    Arrays.sort(L);
    Arrays.sort(R);
   
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
        int l = arr[i][0];
        int r = arr[i][1];
   
        // Find the count of segments
        // on left of ith segment
        int x = lower_bound(L, 0,N, l);
   
        // Find the count of segments
        // on right of ith segment
        int y = N-lower_bound(R, 0,N, r+1);
   
        // Find the total segments not
        // intersecting with the current
        // segment
        int cnt = x + y;
       
        // Store the count of segments
        // that intersect with the
        // ith segment
        cnt = N - cnt - 1;
   
        // Update the value of count
        count = Math.max(count, cnt);
    }
   
    // Return  the resultant count
    return count;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[][] = { { 1, 6 }, { 5, 5 }, { 2, 3 } };
    int N = arr.length;
    System.out.println(maximumIntersections(arr, N));
}
}
 
// This code is contributed by stream_cipher.

Python3




# Python 3 program for the above approach
from bisect import bisect_left, bisect_right
 
 
def lower_bound(a, low, high, element):
 
    while(low < high):
 
        middle = low + (high - low) // 2
        if(element > a[middle]):
            low = middle + 1
        else:
            high = middle
 
    return low
 
 
# Function to find the maximum number
# of intersections one segment has with
# all the other given segments
def maximumIntersections(arr,
                         N):
 
    # Stores the resultant maximum count
    count = 0
 
    # Stores the starting and the
    # ending points
    L = [0]*N
    R = [0]*N
 
    for i in range(N):
        L[i] = arr[i][0]
        R[i] = arr[i][1]
 
    # Sort arrays points in the
    # ascending order
    L.sort()
    R.sort()
 
    # Traverse the array arr[]
    for i in range(N):
        l = arr[i][0]
        r = arr[i][1]
 
        # Find the count of segments
        # on left of ith segment
        x = lower_bound(L, 0, N, l)
 
        # Find the count of segments
        # on right of ith segment
        y = N-lower_bound(R, 0, N, r+1)
 
        # Find the total segments not
        # intersecting with the current
        # segment
        cnt = x + y
 
        # Store the count of segments
        # that intersect with the
        # ith segment
        cnt = N - cnt - 1
 
        # Update the value of count
        count = max(count, cnt)
 
    # Return  the resultant count
    return count
 
# Driver Code
if __name__ == "__main__":
 
    arr = [[1, 6], [5, 5], [2, 3]]
    N = len(arr)
    print(maximumIntersections(arr, N))
 
    # This code is contributed by ukasp.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
static int lower_bound(int[] a, int low,
                       int high, long element)
{
    while(low < high)
    {
        int middle = low + (high - low) / 2;
         
        if (element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
 
static int maximumIntersections(int [,]arr,
                                int N)
{
     
    // Stores the resultant maximum count
    int count = 0;
   
    // Stores the starting and the
    // ending points
    int[] L = new int[N];
    int[] R = new int[N];
    for(int i = 0; i < N; i++)
    {
        L[i] = arr[i, 0];
        R[i] = arr[i, 1];
    }
   
    // Sort arrays points in the
    // ascending order
    Array.Sort(L);
    Array.Sort(R);
   
    // Traverse the array arr[]
    for(int i = 0; i < N; i++)
    {
        int l = arr[i, 0];
        int r = arr[i, 1];
   
        // Find the count of segments
        // on left of ith segment
        int x = lower_bound(L, 0, N, l);
   
        // Find the count of segments
        // on right of ith segment
        int y = N-lower_bound(R, 0, N, r + 1);
   
        // Find the total segments not
        // intersecting with the current
        // segment
        int cnt = x + y;
       
        // Store the count of segments
        // that intersect with the
        // ith segment
        cnt = N - cnt - 1;
   
        // Update the value of count
        count = Math.Max(count, cnt);
    }
     
    // Return the resultant count
    return count;
}
 
// Driver Code
public static void Main()
{
    int [,]arr = new int[3, 2]{ { 1, 6 },
                                { 5, 5 },
                                { 2, 3 } };
    int N = 3;
     
    Console.Write(maximumIntersections(arr, N));
}
}
 
// This code is contributed by SURENDRA_GANGWAR

Javascript




<script>
 
// Javascript program for the above approach
function lower_bound(a, low, high, element)
{
    while(low < high)
    {
        let middle = low + Math.floor(
            (high - low) / 2);
             
        if (element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
 
// Function to find the maximum number
// of intersections one segment has with
// all the other given segments
function maximumLetersections(arr, N)
{
     
    // Stores the resultant maximum count
    let count = 0;
    
    // Stores the starting and the
    // ending polets
    let L = Array.from({length: N}, (_, i) => 0);
    let R = Array.from({length: N}, (_, i) => 0);
    for(let i = 0; i < N; i++)
    {
        L[i] = arr[i][0];
        R[i] = arr[i][1];
    }
    
    // Sort arrays polets in the
    // ascending order
    L.sort();
    R.sort();
    
    // Traverse the array arr[]
    for(let i = 0; i < N; i++)
    {
        let l = arr[i][0];
        let r = arr[i][1];
    
        // Find the count of segments
        // on left of ith segment
        let x = lower_bound(L, 0, N, l);
    
        // Find the count of segments
        // on right of ith segment
        let y = N-lower_bound(R, 0, N, r + 1);
    
        // Find the total segments not
        // letersecting with the current
        // segment
        let cnt = x + y;
        
        // Store the count of segments
        // that letersect with the
        // ith segment
        cnt = N - cnt - 1;
    
        // Update the value of count
        count = Math.max(count, cnt);
    }
    
    // Return the resultant count
    return count;
}
 
// Driver Code
let arr = [ [ 1, 6 ], [ 5, 5 ], [ 2, 3 ] ];
let N = arr.length;
 
document.write(maximumLetersections(arr, N));
 
// This code is contributed by susmitakundugoaldanga
 
</script>
Output: 
2

 

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :