Skip to content
Related Articles

Related Articles

Improve Article

Maximum number of intervals that an interval can intersect

  • Difficulty Level : Hard
  • Last Updated : 03 Jun, 2021

Given an array arr[] consisting of N intervals of the form of [L, R], where L, R denotes the start and end positions of the interval, the task is to count the maximum number of intervals that an interval can intersect with each other.

Examples:

Input: arr[] = {{1, 2}, {3, 4}, {2, 5}}
Output: 3
Explanation: The required set of intervals are {1, 2}, {2, 5}, {3, 4} as {2, 5} intersect all other intervals.

Input: arr[] = {{1, 3}, {2, 4}, {3, 5}, {8, 11}}
Output: 3
Explanation: The required set of intervals are {1, 3}, {2, 4}, {3, 5} as {2, 4} intersect all other intervals.

Naive Approach: The simplest approach is to traverse the array and for each interval, count the number of intervals it intersects using a nested loop. After checking for each interval, print the maximum number of intervals that an interval can intersect.



Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the maximum number
// of intervals that an interval
// can intersect
void findMaxIntervals(
    vector<pair<int, int> > v, int n)
{
    // Store the required answer
    int maxi = 0;
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++) {
 
        // Store the number of
        // intersecting intervals
        int c = n;
 
        // Iterate in the range[0, n-1]
        for (int j = 0; j < n; j++) {
 
            // Check if jth interval lies
            // outside the ith interval
            if (v[i].second < v[j].first
                || v[i].first > v[j].second) {
                c--;
            }
        }
 
        // Update the overall maximum
        maxi = max(c, maxi);
    }
 
    // Print the answer
    cout << maxi;
}
 
// Driver Code
int main()
{
    vector<pair<int, int> > arr
        = { { 1, 2 },
            { 3, 4 },
            { 2, 5 } };
    int N = arr.size();
 
    // Function Call
    findMaxIntervals(arr, N);
 
    return 0;
}

Java




// Java implementation of the approach
import java.util.*;
class GFG
{
 
  static class Pair
  {
    int first, second;
    public Pair(int first, int second)
    {
      this.first = first;
      this.second = second;
    }
  }
 
  // Function to count the maximum number
  // of intervals that an interval
  // can intersect
  static void findMaxIntervals(ArrayList<Pair> v, int n)
  {
 
    // Store the required answer
    int maxi = 0;
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++)
    {
 
      // Store the number of
      // intersecting intervals
      int c = n;
 
      // Iterate in the range[0, n-1]
      for (int j = 0; j < n; j++) {
 
        // Check if jth interval lies
        // outside the ith interval
        if (v.get(i).second < v.get(j).first
            || v.get(i).first > v.get(j).second) {
          c--;
        }
      }
 
      // Update the overall maximum
      maxi = Math.max(c, maxi);
    }
 
    // Print the answer
    System.out.print(maxi);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    ArrayList<Pair> arr = new ArrayList<>();
    arr.add(new Pair(1,2));
    arr.add(new Pair(3,4));
    arr.add(new Pair(2,5));
 
    int N = arr.size();
 
    // Function Call
    findMaxIntervals(arr, N);
  }
}
 
// This code is contributed by susmitakundugoaldnga.

Python3




# Python3 program for the above approach
 
# Function to count the maximum number
# of intervals that an interval
# can intersect
def findMaxIntervals(v, n) :
    
    # Store the required answer
    maxi = 0
     
    # Traverse all the intervals
    for i in range(n) :
    
        # Store the number of
        # intersecting intervals
        c = n
    
        # Iterate in the range[0, n-1]
        for j in range(n) :
    
            # Check if jth interval lies
            # outside the ith interval
            if (v[i][1] < v[j][0] or v[i][0] > v[j][1]) :
             
                c -= 1
    
        # Update the overall maximum
        maxi = max(c, maxi)
    
    # Print the answer
    print(maxi)
     
    # Driver code
arr = []
arr.append((1,2))
arr.append((3,4))
arr.append((2,5))
N = len(arr)
 
# Function Call
findMaxIntervals(arr, N)
 
# This code is contributed by divyeshrabadiya07.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
     
    // Function to count the maximum number
    // of intervals that an interval
    // can intersect
    static void findMaxIntervals(List<Tuple<int, int> > v, int n)
    {
       
        // Store the required answer
        int maxi = 0;
       
        // Traverse all the intervals
        for (int i = 0; i < n; i++)
        {
       
            // Store the number of
            // intersecting intervals
            int c = n;
       
            // Iterate in the range[0, n-1]
            for (int j = 0; j < n; j++)
            {
       
                // Check if jth interval lies
                // outside the ith interval
                if (v[i].Item2 < v[j].Item1
                    || v[i].Item1 > v[j].Item2)
                {
                    c--;
                }
            }
       
            // Update the overall maximum
            maxi = Math.Max(c, maxi);
        }
       
        // Print the answer
        Console.Write(maxi);
    }
 
  // Driver code
  static void Main()
  {
    List<Tuple<int, int>> arr = new List<Tuple<int, int>>();
    arr.Add(new Tuple<int,int>(1,2));
    arr.Add(new Tuple<int,int>(3,4));
    arr.Add(new Tuple<int,int>(2,5));
    int N = arr.Count;
   
    // Function Call
    findMaxIntervals(arr, N);
  }
}
 
// This code is contributed by divyesh072019.

Javascript




<script>
 
// Javascript program for the above approach
 
// Function to count the maximum number
// of intervals that an interval
// can intersect
function findMaxIntervals( v, n)
{
    // Store the required answer
    var maxi = 0;
 
    // Traverse all the intervals
    for (var i = 0; i < n; i++) {
 
        // Store the number of
        // intersecting intervals
        var c = n;
 
        // Iterate in the range[0, n-1]
        for (var j = 0; j < n; j++) {
 
            // Check if jth interval lies
            // outside the ith interval
            if (v[i][1] < v[j][0]
                || v[i][0] > v[j][1]) {
                c--;
            }
        }
 
        // Update the overall maximum
        maxi = Math.max(c, maxi);
    }
 
    // Print the answer
    document.write( maxi);
}
 
// Driver Code
var arr
    = [ [ 1, 2 ],
        [ 3, 4 ],
        [ 2, 5 ] ];
var N = arr.length;
 
// Function Call
findMaxIntervals(arr, N);
 
</script>
Output: 
3

 

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

Efficient Approach: The above approach can be optimized by instead of counting the number of intersections, count the number of intervals that do not intersect. The intervals that do not intersect with a particular interval can be divided into two disjoint categories: intervals that fall completely to the left or completely to the right. Using this idea, follow the steps below to solve the problem:

  • Create a hashmap, say M, to map the number of intervals that do not intersect with each interval.
  • Sort the intervals on the basis of their starting point.
  • Traverse the intervals using the variable i
    • Initialize ans as -1 to store the index of the first interval lying completely to the right of ith interval.
    • Initialize low and high as (i + 1) and (N – 1) and perform a binary search as below:
      • Find the value of mid as (low + high)/2.
      • If the starting position of interval[mid] is greater than the ending position of interval[i], store the current index mid in ans and then check in the left half by updating high to (mid – 1).
      • Else check in the right half by updating low to (mid + 1).
    • If the value of ans is not -1, add (N – ans) to M[interval[i]].
  • Now, sort the intervals on the basis of their ending point.
  • Again, traverse the intervals using the variable i and apply a similar approach as above to find the intervals lying completely to the left of the ith interval.
  • After the loop, traverse the map M and store the minimum value in min.
  • Print the value of (N – min) 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;
 
// Comparator function to sort in
// increasing order of second
// values in each pair
bool compare(pair<int, int> f,
             pair<int, int> s)
{
    return f.second < s.second;
}
 
// Function to hash a pair
struct hash_pair {
    template <class T1, class T2>
    size_t operator()(
        const pair<T1, T2>& p) const
    {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);
        return hash1 ^ hash2;
    }
};
 
// Function to count maximum number
// of intervals that an interval
// can intersect
void findMaxIntervals(
    vector<pair<int, int> > v, int n)
{
 
    // Create a hashmap
    unordered_map<pair<int, int>,
                  int,
                  hash_pair>
        um;
 
    // Sort by starting position
    sort(v.begin(), v.end());
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++) {
 
        // Initialize um[v[i]] as 0
        um[v[i]] = 0;
 
        // Store the starting and
        // ending point of the
        // ith interval
        int start = v[i].first;
        int end = v[i].second;
 
        // Set low and high
        int low = i + 1;
        int high = n - 1;
 
        // Store the required number
        // of intervals
        int ans = -1;
 
        // Apply binary search to find
        // the number of intervals
        // completely lying to the
        // right of the ith interval
        while (low <= high) {
 
            // Find the mid
            int mid = low + (high - low) / 2;
 
            // Condition for searching
            // in the first half
            if (v[mid].first > end) {
                ans = mid;
                high = mid - 1;
            }
 
            // Otherwise search in the
            // second half
            else {
                low = mid + 1;
            }
        }
 
        // Increment um[v[i]] by n-ans
        // if ans!=-1
        if (ans != -1)
            um[v[i]] = n - ans;
    }
 
    // Sort by ending position
    sort(v.begin(), v.end(), compare);
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++) {
 
        // Store the starting and
        // ending point of the
        // ith interval
        int start = v[i].first;
        int end = v[i].second;
 
        // Set low and high
        int low = 0;
        int high = i - 1;
 
        // Store the required number
        // of intervals
        int ans = -1;
 
        // Apply binary search to
        // find the number of intervals
        // completely lying to the
        // left of the ith interval
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (v[mid].second < start) {
                ans = mid;
                low = mid + 1;
            }
            else {
                high = mid - 1;
            }
        }
 
        // Increment um[v[i]] by ans+1
        // if ans!=-1
        if (ans != -1)
            um[v[i]] += (ans + 1);
    }
 
    // Store the answer
    int res = 0;
 
    // Traverse the map
    for (auto it = um.begin();
         it != um.end(); it++) {
 
        // Update the overall answer
        res = max(res, n - it->second);
    }
 
    // Print the answer
    cout << res;
}
 
// Driver Code
int main()
{
    vector<pair<int, int> > arr
        = { { 1, 2 },
            { 3, 4 },
            { 2, 5 } };
 
    int N = arr.size();
 
    // Function Call
    findMaxIntervals(arr, N);
 
    return 0;
}

Java




// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
 
  // Pair class to store in the um as a key
  // with hashcode and equals
  static class Pair
  {
 
    int first;
    int second;
    public Pair(int first, int second)
    {
      this.first = first;
      this.second = second;
    }
 
    @Override public int hashCode()
    {
      final int prime = 31;
      int result = 1;
      result = prime * result + first;
      result = prime * result + second;
      return result;
    }
 
    @Override public boolean equals(Object obj)
    {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      Pair other = (Pair)obj;
      if (first != other.first)
        return false;
      if (second != other.second)
        return false;
      return true;
    }
  }
 
  // Function to count maximum number
  // of intervals that an interval
  // can intersect
  static void findMaxIntervals(ArrayList<Pair> v, int n)
  {
 
    // Create a hashmap
    HashMap<Pair, Integer> um = new HashMap<>();
 
    // Sort by starting position
    Collections.sort(v, (x, y) -> x.first - y.first);
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++) {
 
      // Initialize um for v[i] as 0
      um.put(v.get(i), 0);
 
      // Store the starting and
      // ending point of the
      // ith interval
      int start = v.get(i).first;
      int end = v.get(i).second;
 
      // Set low and high
      int low = i + 1;
      int high = n - 1;
 
      // Store the required number
      // of intervals
      int ans = -1;
 
      // Apply binary search to find
      // the number of intervals
      // completely lying to the
      // right of the ith interval
      while (low <= high) {
 
        // Find the mid
        int mid = low + (high - low) / 2;
 
        // Condition for searching
        // in the first half
        if (v.get(mid).first > end) {
          ans = mid;
          high = mid - 1;
        }
 
        // Otherwise search in the
        // second half
        else {
          low = mid + 1;
        }
      }
 
      // Increment um for v[i] by n-ans
      // if ans!=-1
      if (ans != -1)
        um.put(v.get(i), n - ans);
    }
 
    // Sort by ending position
    Collections.sort(v, (x, y) -> x.second - y.second);
 
    // Traverse all the intervals
    for (int i = 0; i < n; i++) {
 
      // Store the starting and
      // ending point of the
      // ith interval
      int start = v.get(i).first;
      int end = v.get(i).second;
 
      // Set low and high
      int low = 0;
      int high = i - 1;
 
      // Store the required number
      // of intervals
      int ans = -1;
 
      // Apply binary search to
      // find the number of intervals
      // completely lying to the
      // left of the ith interval
      while (low <= high) {
        int mid = low + (high - low) / 2;
        if (v.get(mid).second < start) {
          ans = mid;
          low = mid + 1;
        }
        else {
          high = mid - 1;
        }
      }
 
      // Increment um for v[i] by ans+1
      // if ans!=-1
      if (ans != -1)
        um.put(v.get(i),
               um.get(v.get(i)) + (ans + 1));
    }
 
    // Store the answer
    int res = 0;
 
    // Traverse the map
    for (int second : um.values()) {
 
      // Update the overall answer
      res = Math.max(res, n - second);
    }
 
    // Print the answer
    System.out.println(res);
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    ArrayList<Pair> arr = new ArrayList<>();
    arr.add(new Pair(1, 2));
    arr.add(new Pair(3, 4));
    arr.add(new Pair(2, 5));
 
    int N = arr.size();
 
    // Function Call
    findMaxIntervals(arr, N);
  }
}
 
// This code is contributed by Kingash.
Output: 
3

 

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

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 :