Maximum number of overlapping Intervals

Last Updated : 8 Aug, 2025

Given an array of intervals arr[] where each interval is represented by two integers [start, end] (inclusive). Find the maximum number of intervals that overlap at any point in time.

Examples: 

Input: arr[] = [[1, 2], [2, 4], [3, 6]] 
Output:
Explanation: The maximum overlapping intervals are 2 (between (1 2) and (2 4) or between (2 4) and (3 6)) 

ovlr


Input: arr[] = [[1, 8], [2, 5], [5, 6], [3, 7]] 
Output: 4
Explanation: The maximum overlapping intervals are 4 (between (1, 8), (2, 5), (5, 6) and (3, 7))

Try It Yourself
redirect icon

[Naive Approach] Using nested loop : O(n × (maxi - mini)) Time and O(1) Space

The main idea is to traverse from minimum to the maximum of intervals and check for maximum number of intervals overlapping for each interval.

C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

int overlapInt(vector<vector<int>> &arr){
    int n = arr.size();
    int mini = INT_MAX;
    int maxi = INT_MIN;
    for(auto &it : arr){
        mini = min(mini, it[0]);
        maxi = max(maxi, it[1]);
    }
    int count = 0;
    // Iterate over the arr 
    // in order to find overlaps
    for(int i = mini; i < maxi; i++) {
        
        // for temporarily counting intervals
        int temp = 0;
        for(int j = 0; j < n; j++){
            if(arr[j][0] <= i && arr[j][1] >= i){
                temp++;
            }
        }
        // update value of count
        count = max(temp, count);
    }
    return count;
}

int main() {
    vector<vector<int>> arr = {{1, 8}, {2, 5}, {5, 6}, {3, 7}};
    int ans = overlapInt(arr);
    cout << ans << endl;
}
Java
import java.util.Arrays;

public class GfG {

    public static int overlapInt(int[][] arr) {
        int n = arr.length;
        int mini = Integer.MAX_VALUE;
        int maxi = Integer.MIN_VALUE;

        for (int[] it : arr) {
            mini = Math.min(mini, it[0]);
            maxi = Math.max(maxi, it[1]);
        }

        int count = 0;

        // Iterate over the arr 
        // in order to find overlaps
        for (int i = mini; i < maxi; i++) {

            // for temporarily counting intervals
            int temp = 0;
            for (int j = 0; j < n; j++) {
                if (arr[j][0] <= i && arr[j][1] >= i) {
                    temp++;
                }
            }

            // update value of count
            count = Math.max(temp, count);
        }

        return count;
    }

    public static void main(String[] args) {
        int[][] arr = {{1, 8}, {2, 5}, {5, 6}, {3, 7}};
        int ans = overlapInt(arr);
        System.out.println(ans); 
    }
}
Python
def overlapInt(arr):
    n = len(arr)
    mini = float('inf')
    maxi = float('-inf')
    
    for it in arr:
        mini = min(mini, it[0])
        maxi = max(maxi, it[1])
    
    count = 0
    
    # Iterate over the arr 
    # in order to find overlaps
    for i in range(mini, maxi):
        
        # for temporarily counting intervals
        temp = 0
        for j in range(n):
            if arr[j][0] <= i and arr[j][1] >= i:
                temp += 1
        
        # update value of count
        count = max(temp, count)
    
    return count


arr = [[1, 8], [2, 5], [5, 6], [3, 7]]
ans = overlapInt(arr)
print(ans)  
C#
using System;

public class GfG
{
    public static int overlapInt(int[][] arr)
    {
        int n = arr.Length;
        int mini = int.MaxValue;
        int maxi = int.MinValue;

        for (int i = 0; i < n; i++)
        {
            mini = Math.Min(mini, arr[i][0]);
            maxi = Math.Max(maxi, arr[i][1]);
        }

        int count = 0;

        // Iterate over the arr 
        // in order to find overlaps
        for (int i = mini; i < maxi; i++)
        {
            // for temporarily counting intervals
            int temp = 0;
            for (int j = 0; j < n; j++)
            {
                if (arr[j][0] <= i && arr[j][1] >= i)
                {
                    temp++;
                }
            }

            // update value of count
            count = Math.Max(temp, count);
        }

        return count;
    }

    public static void Main()
    {
        int[][] arr = new int[][]
        {
            new int[] {1, 8},
            new int[] {2, 5},
            new int[] {5, 6},
            new int[] {3, 7},
        };

        int ans = overlapInt(arr);
        Console.WriteLine(ans); 
    }
}
JavaScript
function overlapInt(arr) {
    let n = arr.length;
    let mini = Infinity;
    let maxi = -Infinity;

    for (let i = 0; i < n; i++) {
        mini = Math.min(mini, arr[i][0]);
        maxi = Math.max(maxi, arr[i][1]);
    }

    let count = 0;

    // Iterate over the arr 
    // in order to find overlaps
    for (let i = mini; i < maxi; i++) {

        // for temporarily counting intervals
        let temp = 0;
        for (let j = 0; j < n; j++) {
            if (arr[j][0] <= i && arr[j][1] >= i) {
                temp++;
            }
        }

        // update value of count
        count = Math.max(temp, count);
    }

    return count;
}

// Driver code
let arr = [[1, 8], [2, 5], [5, 6], [3, 7]];
let ans = overlapInt(arr);
console.log(ans);  

Output
4

[Better Approach] Using Difference Array and Prefix Sum - O(max(arr[i][1])) Time and O(max(arr[i][1])) Space

The core idea of this approach is to use the concept of a difference array to track changes in the count of active intervals.
We increment the count at each interval’s start and decrement it just after the interval’s end, then compute the prefix sum of this difference array.
The maximum value obtained in this prefix sum represents the highest number of overlapping intervals at any point.

Note: This approach is inefficient for large interval ranges because it allocates an array of size maxi + 1, leading to high space usage and possible memory overflow. It also wastes time on prefix sum computation over unused indices, making it unsuitable when interval values are large or sparse without applying coordinate compression.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int overlapInt(vector<vector<int>> &arr){
    
    int maxi = -1;
     
    // find the max value occuring 
    // inside the interval
    for(int i=0;i<arr.size();i++){
        maxi = max(maxi, max(arr[i][0],arr[i][1]));
    }
    
    // construct a difference array 
    vector<int> v(maxi+1, 0);
    for(int i=0;i<arr.size();i++){
        
        // v[l] will be incremented by 1
        v[arr[i][0]] += 1;
        if(arr[i][1]<maxi){
            v[arr[i][1] + 1] -= 1;
        }
    }
    
    // prefix sum
    for(int i=1;i<v.size();i++){
        v[i] += v[i-1];
    }
    return *max_element(v.begin(),v.end());
}
int main() {
    vector<vector<int>> arr
        = { { 1, 8 }, { 2, 5 }, { 5, 6 }, { 3, 7} };
    int ans = overlapInt(arr);
    cout<<ans<<endl;
    
    return 0;
}
Java
import java.util.Arrays;
public class GFG {
    static int overlapInt(int[][] arr) {
        int maxi = -1;

        // find the max value occuring 
        // inside the interval
        for (int i = 0; i < arr.length; i++) {
            maxi = Math.max(maxi,
                   Math.max(arr[i][0], arr[i][1]));
        }

        // construct a difference array 
        int[] v = new int[maxi + 1];
        for (int i = 0; i < arr.length; i++) {

            // v[l] will be incremented by 1
            v[arr[i][0]] += 1;
            if (arr[i][1] < maxi) {
                v[arr[i][1] + 1] -= 1;
            }
        }

        // prefix sum
        for (int i = 1; i < v.length; i++) {
            v[i] += v[i - 1];
        }

        return Arrays.stream(v).max().getAsInt();
    }

    public static void main(String[] args) {
        
        int[][] arr = { {1, 8}, {2, 5}, {5, 6}, {3, 7} };
        int ans = overlapInt(arr);
        System.out.println(ans);
    }
}
Python
def overlapInt(arr):
    maxi = -1

    # find the max value occuring 
    # inside the interval
    for i in range(len(arr)):
        maxi = max(maxi, max(arr[i][0], arr[i][1]))

    # fonstruct a difference array 
    v = [0] * (maxi + 1)
    for i in range(len(arr)):

        # v[l] will be incremented by 1
        v[arr[i][0]] += 1
        if arr[i][1] < maxi:
            v[arr[i][1] + 1] -= 1

    # prefix sum
    for i in range(1, len(v)):
        v[i] += v[i - 1]

    return max(v)

if __name__ == "__main__":
    arr = [[1, 8], [2, 5], [5, 6], [3, 7]]
    ans = overlapInt(arr)
    print(ans)
C#
using System;
using System.Linq;

class GFG {
    static int overlapInt(int[][] arr) {
        int maxi = -1;

        // find the max value occuring 
        // inside the interval
        for (int i = 0; i < arr.Length; i++) {
            maxi = Math.Max(maxi, Math.Max(arr[i][0], arr[i][1]));
        }

        // construct a difference array 
        int[] v = new int[maxi + 1];
        for (int i = 0; i < arr.Length; i++) {

            // v[l] will be incremented by 1
            v[arr[i][0]] += 1;
            if (arr[i][1] < maxi) {
                v[arr[i][1] + 1] -= 1;
            }
        }

        // prefix sum
        for (int i = 1; i < v.Length; i++) {
            v[i] += v[i - 1];
        }

        return v.Max();
    }

    static void Main() {
        int[][] arr = new int[][] {
            new int[] { 1, 8 },
            new int[] { 2, 5 },
            new int[] { 5, 6 },
            new int[] { 3, 7 }
        };

        int ans = overlapInt(arr);
        Console.WriteLine(ans);
    }
}
JavaScript
function overlapInt(arr) {
    let maxi = -1;

    // find the max value occuring 
    // inside the interval
    for (let i = 0; i < arr.length; i++) {
        maxi = Math.max(maxi, Math.max(arr[i][0], arr[i][1]));
    }

    // construct a difference array 
    let v = new Array(maxi + 1).fill(0);
    for (let i = 0; i < arr.length; i++) {

        // v[l] will be incremented by 1
        v[arr[i][0]] += 1;
        if (arr[i][1] < maxi) {
            v[arr[i][1] + 1] -= 1;
        }
    }

    // prefix sum
    for (let i = 1; i < v.length; i++) {
        v[i] += v[i - 1];
    }

    return Math.max(...v);
}

// Driver code
const arr = [ [1, 8], [2, 5], [5, 6], [3, 7] ];
const ans = overlapInt(arr);
console.log(ans);

Output
4

[Expected Approach - 1] Using sorting algorithm - O(n × logn) Time and O(n) Space

The main idea behind this approach is to pair up the first element to a character "x" and second element to a character "y" and eventually sort the pairs and increase the counter when the character "x" is found and decrease when character "y" is found. Return the maximum counter achieved.

Step by step Approach:

  • Create a array to store interval start and end points with labels x for start and y for end.
  • Loop through each interval and push its start and end into the vector.
  • Sort the vector of points, this will automatically order by time, and x comes before y if equal.
  • Traverse the sorted vector, increasing a counter for x (start of interval) and decreasing it for y (end of interval).
  • After each step, update the maximum overlap count found so far.
  • Return the maximum number of overlapping intervals.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int overlapInt(vector<vector<int>> &arr) {

    int ans = 0;
    int count = 0;
    int n = arr.size();

    // Each element: {coordinate, type}
    // type = 0 for 'start', 1 for 'end'
    vector<vector<int>> data;

    // Store start and end points
    for (int i = 0; i < n; i++) {
        // start
        data.push_back({arr[i][0], 0}); 
        // end
        data.push_back({arr[i][1], 1}); 
    }

    // Sort by coordinate; start before end if equal
    sort(data.begin(), data.end(), [](const vector<int> &a, const vector<int> &b) {
        if (a[0] != b[0]) return a[0] < b[0];
        // start(0) before end(1)
        return a[1] < b[1];
    });

    // Count overlaps
    for (int i = 0; i < data.size(); i++) {
        // start
        if (data[i][1] == 0) count++;
        
        // end
        else count--;                
        ans = max(ans, count);
    }

    return ans;
}

int main() {
    vector<vector<int>> arr =
        {{1, 8}, {2, 5}, {5, 6}, {3, 7}, {6, 10}};
    int ans = overlapInt(arr);
    cout << ans << endl;
    return 0;
}
Java
import java.util.*;

class GfG {

    public static int overlapInt(int[][] arr) {

        int ans = 0;
        int count = 0;

        // Each element: [coordinate, type]
        // type = 0 for 'start', 1 for 'end'
        int[][] data = new int[arr.length * 2][2];

        int idx = 0;
        for (int i = 0; i < arr.length; i++) {
            data[idx][0] = arr[i][0];
            data[idx++][1] = 0; // start point
            data[idx][0] = arr[i][1];
            data[idx++][1] = 1; // end point
        }

        // sort by coordinate; if same, start comes before end
        Arrays.sort(data, (a, b) -> {
            if (a[0] != b[0]) return a[0] - b[0];
            return a[1] - b[1]; // start(0) before end(1)
        });

        // Count overlaps
        for (int[] point : data) {
            // start
            if (point[1] == 0) count++;  
            
            // end
            else count--;               
            ans = Math.max(ans, count);
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] arr = {
            {1, 8},
            {2, 5},
            {5, 6},
            {3, 7}
        };
        int res = overlapInt(arr);
        System.out.println(res);
    }
}
Python
def overlapInt(arr):

    ans = 0
    count = 0
    data = []

    # storing the x and y
    # coordinates in data vector
    for i in range(len(arr)):

        data.append([arr[i][0], 'x'])
        data.append([arr[i][1], 'y'])

    data = sorted(data)

    # Traverse the data vector to
    # count number of overlaps
    for i in range(len(data)):

        # if x occur it means a new range
        # is added so we increase count
        if (data[i][1] == 'x'):
            count += 1

        # if y occur it means a range
        # is ended so we decrease count
        if (data[i][1] == 'y'):
            count -= 1

        # updating the value of ans
        # after every traversal
        ans = max(ans, count)

    return ans


if __name__ == "__main__":
    arr = [ [ 1, 8 ], [ 2, 5 ], [ 5, 6 ], [ 3, 7] ]
    res = overlapInt(arr)
    print(res)
C#
using System;
using System.Collections.Generic;

class GfG {
    static int overlapInt(int[,] arr) {
        int ans = 0;
        int count = 0;

        // Each element: [coordinate, type]
        // type = 0 for 'start', 1 for 'end'
        var data = new List<int[]>();

        // Store start and end points
        for (int i = 0; i < arr.GetLength(0); i++) {
             // start
            data.Add(new int[] { arr[i, 0], 0 });
            // end
            data.Add(new int[] { arr[i, 1], 1 }); 
        }

        // Sort by coordinate; start before end if same
        data.Sort((a, b) => {
            if (a[0] != b[0]) return a[0].CompareTo(b[0]);
            return a[1].CompareTo(b[1]); // start(0) before end(1)
        });

        // Count overlaps
        foreach (var point in data) {
            if (point[1] == 0) count++; // start
            else count--;               // end
            ans = Math.Max(ans, count);
        }

        return ans;
    }

    public static void Main(string[] args) {
        int[,] arr = new int[,] {
            { 1, 8 },
            { 2, 5 },
            { 5, 6 },
            { 3, 7 }
        };

        int res = overlapInt(arr);
        Console.WriteLine(res);
    }
}
JavaScript
function overlapInt(arr) {
    
    var ans = 0;
    var count = 0;
    var data = [];

    // Storing the x and y
    // coordinates in data vector
    for(var i = 0; i < arr.length; i++) {
        
        data.push([arr[i][0], 'x']);
        data.push([arr[i][1], 'y']);
    }

    // Sorting of ranges
    data.sort();

    for(var i = 0; i < data.length; i++) {
        if (data[i][1] == 'x')
            count++;
        if (data[i][1] == 'y')
            count--;

        ans = Math.max(ans, count);
    }
    return ans;
}

// Driver code
var arr = [ [ 1, 8 ], [ 2, 5 ], [ 5, 6 ], [ 3, 7] ];
let res = overlapInt(arr);
console.log(res);

Output
4

[Expected Approach - 2] Sweep Line Algorithm using Ordered Map (Coordinate Change Tracking)

The idea in this approach is to treat each interval’s start as an increase in active intervals and its end as a decrease right after it.
We record these changes in an ordered map, where keys are coordinates and values represent how the count changes at that point.
By traversing the map in sorted order and maintaining a running sum of active intervals, we can efficiently track the maximum overlap at any point.
This avoids iterating over the entire range and only processes the coordinates where a change actually occurs.

C++
#include <iostream>
#include <vector>
#include <map>
using namespace std;

int overlapInt(vector<vector<int>> &arr) {
    
    // coordinate → change in active count
    map<int, int> mp; 

    // mark +1 at start, -1 at end+1
    for (auto &interval : arr) {
        // start
        mp[interval[0]]++;      
        // just after end
        mp[interval[1] + 1]--;  
    }

    int ans = 0, count = 0;
    // rraverse in sorted coordinate order
    for (auto &p : mp) {
        count += p.second;
        ans = max(ans, count);
    }

    return ans;
}

int main() {
    vector<vector<int>> arr = {
        {1, 8}, {2, 5}, {5, 6}, {3, 7}, {6, 10}
    };
    cout << overlapInt(arr) << endl;
    return 0;
}
Java
import java.util.Map;
import java.util.TreeMap;

class GfG {

    static int overlapInt(int[][] arr) {

        // coordinate → change in active count
        TreeMap<Integer, Integer> mp = new TreeMap<>();

        // mark +1 at start, -1 at end+1
        for (int[] interval : arr) {
            // start
            mp.put(interval[0], mp.getOrDefault(interval[0], 0) + 1);
            // just after end
            mp.put(interval[1] + 1, mp.getOrDefault(interval[1] + 1, 0) - 1);
        }

        int ans = 0, count = 0;
        // traverse in sorted coordinate order
        for (int change : mp.values()) {
            count += change;
            ans = Math.max(ans, count);
        }

        return ans;
    }

    public static void main(String[] args) {
        int[][] arr = {
            {1, 8}, {2, 5}, {5, 6}, {3, 7}, {6, 10}
        };
        System.out.println(overlapInt(arr));
    }
}
Python
def overlapInt(arr):

    # coordinate → change in active count
    mp = {}

    # mark +1 at start, -1 at end+1
    for interval in arr:
        # start
        mp[interval[0]] = mp.get(interval[0], 0) + 1
        # just after end
        mp[interval[1] + 1] = mp.get(interval[1] + 1, 0) - 1

    ans = 0
    count = 0
    # traverse in sorted coordinate order
    for key in sorted(mp.keys()):
        count += mp[key]
        ans = max(ans, count)

    return ans

if __name__ == "__main__":
    arr = [
        [1, 8], [2, 5], [5, 6], [3, 7], [6, 10]
    ]
    print(overlapInt(arr))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int overlapInt(int[,] arr) {

        // coordinate → change in active count
        var mp = new SortedDictionary<int, int>();

        // mark +1 at start, -1 at end+1
        for (int i = 0; i < arr.GetLength(0); i++) {
            // start
            if (!mp.ContainsKey(arr[i, 0])) mp[arr[i, 0]] = 0;
            mp[arr[i, 0]] += 1;

            // just after end
            int endKey = arr[i, 1] + 1;
            if (!mp.ContainsKey(endKey)) mp[endKey] = 0;
            mp[endKey] -= 1;
        }

        int ans = 0, count = 0;
        // traverse in sorted coordinate order
        foreach (var kv in mp) {
            count += kv.Value;
            ans = Math.Max(ans, count);
        }

        return ans;
    }

    public static void Main(string[] args) {
        int[,] arr = {
            {1, 8}, {2, 5}, {5, 6}, {3, 7}, {6, 10}
        };
        Console.WriteLine(overlapInt(arr));
    }
}
JavaScript
function overlapInt(arr) {

    // coordinate → change in active count
    let mp = new Map();

    // mark +1 at start, -1 at end+1
    for (let [start, end] of arr) {
        // start
        mp.set(start, (mp.get(start) || 0) + 1);
        // just after end
        mp.set(end + 1, (mp.get(end + 1) || 0) - 1);
    }

    let ans = 0, count = 0;
    // traverse in sorted coordinate order
    let keys = Array.from(mp.keys()).sort((a, b) => a - b);
    for (let key of keys) {
        count += mp.get(key);
        ans = Math.max(ans, count);
    }

    return ans;
}

// Driver Code
let arr = [
    [1, 8], [2, 5], [5, 6], [3, 7], [6, 10]
];
console.log(overlapInt(arr));

Output
4

Time Complexity: O(n × log n), this is because inserting 2n points into an ordered map takes O(log n) time each, and traversing the sorted keys takes O(n). The sorting is inherently handled by the map’s ordering.
Auxiliary Space: O(n), the ordered map stores at most 2n entries (start and end+1 for each interval), so the extra space used is proportional to the number of intervals.

Comment