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: 2 Explanation: The maximum overlapping intervals are 2 (between (1 2) and (2 4) or between (2 4) and (3 6))
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))
[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>usingnamespacestd;intoverlapInt(vector<vector<int>>&arr){intn=arr.size();intmini=INT_MAX;intmaxi=INT_MIN;for(auto&it:arr){mini=min(mini,it[0]);maxi=max(maxi,it[1]);}intcount=0;// Iterate over the arr // in order to find overlapsfor(inti=mini;i<maxi;i++){// for temporarily counting intervalsinttemp=0;for(intj=0;j<n;j++){if(arr[j][0]<=i&&arr[j][1]>=i){temp++;}}// update value of countcount=max(temp,count);}returncount;}intmain(){vector<vector<int>>arr={{1,8},{2,5},{5,6},{3,7}};intans=overlapInt(arr);cout<<ans<<endl;}
Java
importjava.util.Arrays;publicclassGfG{publicstaticintoverlapInt(int[][]arr){intn=arr.length;intmini=Integer.MAX_VALUE;intmaxi=Integer.MIN_VALUE;for(int[]it:arr){mini=Math.min(mini,it[0]);maxi=Math.max(maxi,it[1]);}intcount=0;// Iterate over the arr // in order to find overlapsfor(inti=mini;i<maxi;i++){// for temporarily counting intervalsinttemp=0;for(intj=0;j<n;j++){if(arr[j][0]<=i&&arr[j][1]>=i){temp++;}}// update value of countcount=Math.max(temp,count);}returncount;}publicstaticvoidmain(String[]args){int[][]arr={{1,8},{2,5},{5,6},{3,7}};intans=overlapInt(arr);System.out.println(ans);}}
Python
defoverlapInt(arr):n=len(arr)mini=float('inf')maxi=float('-inf')foritinarr:mini=min(mini,it[0])maxi=max(maxi,it[1])count=0# Iterate over the arr # in order to find overlapsforiinrange(mini,maxi):# for temporarily counting intervalstemp=0forjinrange(n):ifarr[j][0]<=iandarr[j][1]>=i:temp+=1# update value of countcount=max(temp,count)returncountarr=[[1,8],[2,5],[5,6],[3,7]]ans=overlapInt(arr)print(ans)
C#
usingSystem;publicclassGfG{publicstaticintoverlapInt(int[][]arr){intn=arr.Length;intmini=int.MaxValue;intmaxi=int.MinValue;for(inti=0;i<n;i++){mini=Math.Min(mini,arr[i][0]);maxi=Math.Max(maxi,arr[i][1]);}intcount=0;// Iterate over the arr // in order to find overlapsfor(inti=mini;i<maxi;i++){// for temporarily counting intervalsinttemp=0;for(intj=0;j<n;j++){if(arr[j][0]<=i&&arr[j][1]>=i){temp++;}}// update value of countcount=Math.Max(temp,count);}returncount;}publicstaticvoidMain(){int[][]arr=newint[][]{newint[]{1,8},newint[]{2,5},newint[]{5,6},newint[]{3,7},};intans=overlapInt(arr);Console.WriteLine(ans);}}
JavaScript
functionoverlapInt(arr){letn=arr.length;letmini=Infinity;letmaxi=-Infinity;for(leti=0;i<n;i++){mini=Math.min(mini,arr[i][0]);maxi=Math.max(maxi,arr[i][1]);}letcount=0;// Iterate over the arr // in order to find overlapsfor(leti=mini;i<maxi;i++){// for temporarily counting intervalslettemp=0;for(letj=0;j<n;j++){if(arr[j][0]<=i&&arr[j][1]>=i){temp++;}}// update value of countcount=Math.max(temp,count);}returncount;}// Driver codeletarr=[[1,8],[2,5],[5,6],[3,7]];letans=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>usingnamespacestd;intoverlapInt(vector<vector<int>>&arr){intmaxi=-1;// find the max value occuring // inside the intervalfor(inti=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(inti=0;i<arr.size();i++){// v[l] will be incremented by 1v[arr[i][0]]+=1;if(arr[i][1]<maxi){v[arr[i][1]+1]-=1;}}// prefix sumfor(inti=1;i<v.size();i++){v[i]+=v[i-1];}return*max_element(v.begin(),v.end());}intmain(){vector<vector<int>>arr={{1,8},{2,5},{5,6},{3,7}};intans=overlapInt(arr);cout<<ans<<endl;return0;}
Java
importjava.util.Arrays;publicclassGFG{staticintoverlapInt(int[][]arr){intmaxi=-1;// find the max value occuring // inside the intervalfor(inti=0;i<arr.length;i++){maxi=Math.max(maxi,Math.max(arr[i][0],arr[i][1]));}// construct a difference array int[]v=newint[maxi+1];for(inti=0;i<arr.length;i++){// v[l] will be incremented by 1v[arr[i][0]]+=1;if(arr[i][1]<maxi){v[arr[i][1]+1]-=1;}}// prefix sumfor(inti=1;i<v.length;i++){v[i]+=v[i-1];}returnArrays.stream(v).max().getAsInt();}publicstaticvoidmain(String[]args){int[][]arr={{1,8},{2,5},{5,6},{3,7}};intans=overlapInt(arr);System.out.println(ans);}}
Python
defoverlapInt(arr):maxi=-1# find the max value occuring # inside the intervalforiinrange(len(arr)):maxi=max(maxi,max(arr[i][0],arr[i][1]))# fonstruct a difference array v=[0]*(maxi+1)foriinrange(len(arr)):# v[l] will be incremented by 1v[arr[i][0]]+=1ifarr[i][1]<maxi:v[arr[i][1]+1]-=1# prefix sumforiinrange(1,len(v)):v[i]+=v[i-1]returnmax(v)if__name__=="__main__":arr=[[1,8],[2,5],[5,6],[3,7]]ans=overlapInt(arr)print(ans)
C#
usingSystem;usingSystem.Linq;classGFG{staticintoverlapInt(int[][]arr){intmaxi=-1;// find the max value occuring // inside the intervalfor(inti=0;i<arr.Length;i++){maxi=Math.Max(maxi,Math.Max(arr[i][0],arr[i][1]));}// construct a difference array int[]v=newint[maxi+1];for(inti=0;i<arr.Length;i++){// v[l] will be incremented by 1v[arr[i][0]]+=1;if(arr[i][1]<maxi){v[arr[i][1]+1]-=1;}}// prefix sumfor(inti=1;i<v.Length;i++){v[i]+=v[i-1];}returnv.Max();}staticvoidMain(){int[][]arr=newint[][]{newint[]{1,8},newint[]{2,5},newint[]{5,6},newint[]{3,7}};intans=overlapInt(arr);Console.WriteLine(ans);}}
JavaScript
functionoverlapInt(arr){letmaxi=-1;// find the max value occuring // inside the intervalfor(leti=0;i<arr.length;i++){maxi=Math.max(maxi,Math.max(arr[i][0],arr[i][1]));}// construct a difference array letv=newArray(maxi+1).fill(0);for(leti=0;i<arr.length;i++){// v[l] will be incremented by 1v[arr[i][0]]+=1;if(arr[i][1]<maxi){v[arr[i][1]+1]-=1;}}// prefix sumfor(leti=1;i<v.length;i++){v[i]+=v[i-1];}returnMath.max(...v);}// Driver codeconstarr=[[1,8],[2,5],[5,6],[3,7]];constans=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>usingnamespacestd;intoverlapInt(vector<vector<int>>&arr){intans=0;intcount=0;intn=arr.size();// Each element: {coordinate, type}// type = 0 for 'start', 1 for 'end'vector<vector<int>>data;// Store start and end pointsfor(inti=0;i<n;i++){// startdata.push_back({arr[i][0],0});// enddata.push_back({arr[i][1],1});}// Sort by coordinate; start before end if equalsort(data.begin(),data.end(),[](constvector<int>&a,constvector<int>&b){if(a[0]!=b[0])returna[0]<b[0];// start(0) before end(1)returna[1]<b[1];});// Count overlapsfor(inti=0;i<data.size();i++){// startif(data[i][1]==0)count++;// endelsecount--;ans=max(ans,count);}returnans;}intmain(){vector<vector<int>>arr={{1,8},{2,5},{5,6},{3,7},{6,10}};intans=overlapInt(arr);cout<<ans<<endl;return0;}
Java
importjava.util.*;classGfG{publicstaticintoverlapInt(int[][]arr){intans=0;intcount=0;// Each element: [coordinate, type]// type = 0 for 'start', 1 for 'end'int[][]data=newint[arr.length*2][2];intidx=0;for(inti=0;i<arr.length;i++){data[idx][0]=arr[i][0];data[idx++][1]=0;// start pointdata[idx][0]=arr[i][1];data[idx++][1]=1;// end point}// sort by coordinate; if same, start comes before endArrays.sort(data,(a,b)->{if(a[0]!=b[0])returna[0]-b[0];returna[1]-b[1];// start(0) before end(1)});// Count overlapsfor(int[]point:data){// startif(point[1]==0)count++;// endelsecount--;ans=Math.max(ans,count);}returnans;}publicstaticvoidmain(String[]args){int[][]arr={{1,8},{2,5},{5,6},{3,7}};intres=overlapInt(arr);System.out.println(res);}}
Python
defoverlapInt(arr):ans=0count=0data=[]# storing the x and y# coordinates in data vectorforiinrange(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 overlapsforiinrange(len(data)):# if x occur it means a new range# is added so we increase countif(data[i][1]=='x'):count+=1# if y occur it means a range# is ended so we decrease countif(data[i][1]=='y'):count-=1# updating the value of ans# after every traversalans=max(ans,count)returnansif__name__=="__main__":arr=[[1,8],[2,5],[5,6],[3,7]]res=overlapInt(arr)print(res)
C#
usingSystem;usingSystem.Collections.Generic;classGfG{staticintoverlapInt(int[,]arr){intans=0;intcount=0;// Each element: [coordinate, type]// type = 0 for 'start', 1 for 'end'vardata=newList<int[]>();// Store start and end pointsfor(inti=0;i<arr.GetLength(0);i++){// startdata.Add(newint[]{arr[i,0],0});// enddata.Add(newint[]{arr[i,1],1});}// Sort by coordinate; start before end if samedata.Sort((a,b)=>{if(a[0]!=b[0])returna[0].CompareTo(b[0]);returna[1].CompareTo(b[1]);// start(0) before end(1)});// Count overlapsforeach(varpointindata){if(point[1]==0)count++;// startelsecount--;// endans=Math.Max(ans,count);}returnans;}publicstaticvoidMain(string[]args){int[,]arr=newint[,]{{1,8},{2,5},{5,6},{3,7}};intres=overlapInt(arr);Console.WriteLine(res);}}
JavaScript
functionoverlapInt(arr){varans=0;varcount=0;vardata=[];// Storing the x and y// coordinates in data vectorfor(vari=0;i<arr.length;i++){data.push([arr[i][0],'x']);data.push([arr[i][1],'y']);}// Sorting of rangesdata.sort();for(vari=0;i<data.length;i++){if(data[i][1]=='x')count++;if(data[i][1]=='y')count--;ans=Math.max(ans,count);}returnans;}// Driver codevararr=[[1,8],[2,5],[5,6],[3,7]];letres=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>usingnamespacestd;intoverlapInt(vector<vector<int>>&arr){// coordinate → change in active countmap<int,int>mp;// mark +1 at start, -1 at end+1for(auto&interval:arr){// startmp[interval[0]]++;// just after endmp[interval[1]+1]--;}intans=0,count=0;// rraverse in sorted coordinate orderfor(auto&p:mp){count+=p.second;ans=max(ans,count);}returnans;}intmain(){vector<vector<int>>arr={{1,8},{2,5},{5,6},{3,7},{6,10}};cout<<overlapInt(arr)<<endl;return0;}
Java
importjava.util.Map;importjava.util.TreeMap;classGfG{staticintoverlapInt(int[][]arr){// coordinate → change in active countTreeMap<Integer,Integer>mp=newTreeMap<>();// mark +1 at start, -1 at end+1for(int[]interval:arr){// startmp.put(interval[0],mp.getOrDefault(interval[0],0)+1);// just after endmp.put(interval[1]+1,mp.getOrDefault(interval[1]+1,0)-1);}intans=0,count=0;// traverse in sorted coordinate orderfor(intchange:mp.values()){count+=change;ans=Math.max(ans,count);}returnans;}publicstaticvoidmain(String[]args){int[][]arr={{1,8},{2,5},{5,6},{3,7},{6,10}};System.out.println(overlapInt(arr));}}
Python
defoverlapInt(arr):# coordinate → change in active countmp={}# mark +1 at start, -1 at end+1forintervalinarr:# startmp[interval[0]]=mp.get(interval[0],0)+1# just after endmp[interval[1]+1]=mp.get(interval[1]+1,0)-1ans=0count=0# traverse in sorted coordinate orderforkeyinsorted(mp.keys()):count+=mp[key]ans=max(ans,count)returnansif__name__=="__main__":arr=[[1,8],[2,5],[5,6],[3,7],[6,10]]print(overlapInt(arr))
C#
usingSystem;usingSystem.Collections.Generic;classGfG{staticintoverlapInt(int[,]arr){// coordinate → change in active countvarmp=newSortedDictionary<int,int>();// mark +1 at start, -1 at end+1for(inti=0;i<arr.GetLength(0);i++){// startif(!mp.ContainsKey(arr[i,0]))mp[arr[i,0]]=0;mp[arr[i,0]]+=1;// just after endintendKey=arr[i,1]+1;if(!mp.ContainsKey(endKey))mp[endKey]=0;mp[endKey]-=1;}intans=0,count=0;// traverse in sorted coordinate orderforeach(varkvinmp){count+=kv.Value;ans=Math.Max(ans,count);}returnans;}publicstaticvoidMain(string[]args){int[,]arr={{1,8},{2,5},{5,6},{3,7},{6,10}};Console.WriteLine(overlapInt(arr));}}
JavaScript
functionoverlapInt(arr){// coordinate → change in active countletmp=newMap();// mark +1 at start, -1 at end+1for(let[start,end]ofarr){// startmp.set(start,(mp.get(start)||0)+1);// just after endmp.set(end+1,(mp.get(end+1)||0)-1);}letans=0,count=0;// traverse in sorted coordinate orderletkeys=Array.from(mp.keys()).sort((a,b)=>a-b);for(letkeyofkeys){count+=mp.get(key);ans=Math.max(ans,count);}returnans;}// Driver Codeletarr=[[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.