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 intersectvoid 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 Codeint 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 approachimport 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 codearr = []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 intersectfunction 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 Codevar arr    = [ [ 1, 2 ],        [ 3, 4 ],        [ 2, 5 ] ];var N = arr.length;Â
// Function CallfindMaxIntervals(arr, N);Â
</script> |
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 pairbool compare(pair<int, int> f,             pair<int, int> s){    return f.second < s.second;}Â
// Function to hash a pairstruct 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 intersectvoid 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 Codeint 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 approachimport 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. |
Python3
from typing import List, Tuplefrom collections import defaultdictÂ
# Function to find the maximum number of intervals that an interval can intersectdef findMaxIntervals(v: List[Tuple[int,int]]) -> None:    # Sort the intervals by their starting position    v.sort()    n = len(v)    # Use a dictionary to store the number of intervals that can intersect with each interval    um = defaultdict(int)Â
    # Iterate through all the intervals    for i in range(n):        # Store the starting and ending point of the current interval        start = v[i][0]        end = v[i][1]Â
        low = i + 1        high = n - 1        ans = -1        # Use binary search to find the number of intervals completely lying to the right of the current interval        while low <= high:            mid = low + (high - low) // 2            if v[mid][0] > end:                ans = mid                high = mid - 1            else:                low = mid + 1Â
        # Increment the number of intersecting intervals in the dictionary        if ans != -1:            um[v[i]] = n - ansÂ
    # Sort the intervals by their ending position    v.sort(key=lambda x: (x[1], x[0]))Â
    # Iterate through all the intervals    for i in range(n):        # Store the starting and ending point of the current interval        start = v[i][0]        end = v[i][1]Â
        low = 0        high = i - 1        ans = -1        # Use binary search to find the number of intervals completely lying to the left of the current interval        while low <= high:            mid = low + (high - low) // 2            if v[mid][1] < start:                ans = mid                low = mid + 1            else:                high = mid - 1Â
        # Increment the number of intersecting intervals in the dictionary        if ans != -1:            um[v[i]] += (ans + 1)Â
    # Find the interval with the maximum number of non-intersecting intervals    res = 0    for key, val in sorted(um.items()):        res = max(res, n - val + 1)    print(res)     Â
arr = [(1, 2), (3, 4), (2, 5)]findMaxIntervals(arr) |
C#
// C# program to implement the approachÂ
using System;using System.Collections.Generic;using System.Linq;Â
class GFG {    // Pair class to store in the um as a key    // with hashcode and equals    private class Pair {        public int first        {            get;            set;        }        public int second        {            get;            set;        }Â
        public Pair(int first, int second)        {            this.first = first;            this.second = second;        }Â
        public override int GetHashCode()        {            int prime = 31;            int result = 1;            result = prime * result + first;            result = prime * result + second;            return result;        }Â
        public override bool Equals(object obj)        {            if (this == obj)                return true;            if (obj == null)                return false;            if (GetType() != obj.GetType())                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(List<Pair> v, int n)    {        // Create a hashmap        Dictionary<Pair, int> um            = new Dictionary<Pair, int>();Â
        // Sort by starting position        v.Sort((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.Add(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 for v[i] by n-ans            // if ans!=-1            if (ans != -1)                um[v[i]] = n - ans;        }Â
        // Sort by ending position        v.Sort((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[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 for v[i] by ans+1            // if ans!=-1            if (ans != -1)                um[v[i]] = um[v[i]] + (ans + 1);        }Â
        // Store the answer        int res = 0;Â
        // Traverse the map        foreach(var entry in um)        {            int second = entry.Value;Â
            // Update the overall answer            res = Math.Max(res, n - second);        }Â
        // Print the answer        Console.WriteLine(res);    }Â
    // Driver Code    public static void Main(string[] args)    {Â
        List<Pair> arr = new List<Pair>();        arr.Add(new Pair(1, 2));        arr.Add(new Pair(3, 4));        arr.Add(new Pair(2, 5));Â
        int N = arr.Count;Â
        // Function Call        FindMaxIntervals(arr, N);    }}Â
// This code is contributed by phasing17 |
Javascript
// JS code to implement the approachÂ
// Function to find the maximum number of intervals that an interval can intersectfunction findMaxIntervals(v) {    // Sort the intervals by their starting position    v.sort((a, b) => {        if (a[0] !== b[0]) {            return a[0] - b[0];        } else {            return a[1] - b[1];        }    });    let n = v.length;    // Use a dictionary to store the number of intervals that can intersect with each interval    let um = new Map();Â
    // Iterate through all the intervals    for (let i = 0; i < n; i++) {        // Store the starting and ending point of the current interval        let start = v[i][0];        let end = v[i][1];Â
        let low = i + 1;        let high = n - 1;        let ans = -1;        // Use binary search to find the number of intervals completely lying to the right of the current interval        while (low <= high) {            let mid = low + Math.floor((high - low) / 2);            if (v[mid][0] > end) {                ans = mid;                high = mid - 1;            } else {                low = mid + 1;            }        }Â
        // Increment the number of intersecting intervals in the dictionary        if (ans !== -1) {            um.set(v[i], n - ans);        }    }Â
    // Sort the intervals by their ending position    v.sort((a, b) => {        if (a[1] == b[1])            return a[0] - b[0];        return a[1] - b[1];    })Â
    // Iterate through all the intervals    for (var i = 0; i < n; i++)    {        // Store the starting and ending point of the current interval        var start = v[i][0]        var end = v[i][1]Â
        var low = 0        var high = i - 1        var ans = -1        // Use binary search to find the number of intervals completely lying to the left of the current interval        while (low <= high)        {            mid = low + Math.floor((high - low) / 2)            if (v[mid][1] < start)            {                ans = mid                low = mid + 1            }            else                high = mid - 1        }Â
        // Increment the number of intersecting intervals in the dictionary        var key = v[i].join("#")        if (!um.hasOwnProperty(key))            um[key] = 0;        if (ans != -1)            um[key] += (ans + 1)    }Â
    // Find the interval with the maximum number of non-intersecting intervals    var res = 0         var vals = Object.values(um)    for (let val of vals)        res = Math.max(res, n - val)    console.log(res)}Â
let arr = [[1, 2], [3, 4], [2, 5]]findMaxIntervals(arr)Â
Â
// This code is contributed by phasing17 |
3
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!
