Merge Overlapping Intervals
Last Updated :
23 Jul, 2025
Given an array of time intervals where arr[i] = [starti, endi], the task is to merge all the overlapping intervals into one and output the result which should have only mutually exclusive intervals.
Given an array of time intervals where arr[i] = [starti, endi], find the merge all the overlapping intervals into one, and output the result containing only mutually exclusive intervals.
Examples:
Input: arr[] = [[1, 3], [2, 4], [6, 8], [9, 10]]
Output: [[1, 4], [6, 8], [9, 10]]
Explanation: In the given intervals, we have only two overlapping intervals [1, 3] and [2, 4]. Therefore, we will merge these two and return [[1, 4]], [6, 8], [9, 10]].
Input: arr[] = [[7, 8], [1, 5], [2, 4], [4, 6]]
Output: [[1, 6], [7, 8]]
Explanation: We will merge the overlapping intervals [[1, 5], [2, 4], [4, 6]] into a single interval [1, 6].
[Naive Approach] Checking All Possible Overlaps – O(n^2) Time and O(n) Space
A simple approach is to group all the intervals by sorting them then start from the first interval and compare it with all other intervals for overlaps. If the first interval overlaps with any other interval, then remove the other interval from the list and merge the other into the first interval. Repeat the same steps for the remaining intervals after the first.
C++
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> mergeOverlap(vector<vector<int>> &arr) {
int n = arr.size();
sort(arr.begin(), arr.end());
vector<vector<int>> res;
// Checking for all possible overlaps
for (int i = 0; i < n; i++) {
int start = arr[i][0];
int end = arr[i][1];
// Skipping already merged intervals
if (!res.empty() && res.back()[1] >= end)
continue;
// Find the end of the merged range
for (int j = i + 1; j < n; j++) {
if (arr[j][0] <= end)
end = max(end, arr[j][1]);
}
res.push_back({start, end});
}
return res;
}
int main() {
vector<vector<int>> arr = {{7, 8}, {1, 5}, {2, 4}, {4, 6}};
vector<vector<int>> res = mergeOverlap(arr);
for (auto interval : res)
cout << interval[0] << " " << interval[1] << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
class GfG {
static ArrayList<int[]> mergeOverlap(int[][] arr) {
int n = arr.length;
Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
ArrayList<int[]> res = new ArrayList<>();
// Checking for all possible overlaps
for (int i = 0; i < n; i++) {
int start = arr[i][0];
int end = arr[i][1];
// Skipping already merged intervals
if (!res.isEmpty() && res.get(res.size() - 1)[1] >= end) {
continue;
}
// Find the end of the merged range
for (int j = i + 1; j < n; j++) {
if (arr[j][0] <= end) {
end = Math.max(end, arr[j][1]);
}
}
res.add(new int[]{start, end});
}
return res;
}
public static void main(String[] args) {
int[][] arr = {{7, 8}, {1, 5}, {2, 4}, {4, 6}};
ArrayList<int[]> res = mergeOverlap(arr);
for (int[] interval : res) {
System.out.println(interval[0] + " " + interval[1]);
}
}
}
Python
def mergeOverlap(arr):
n = len(arr)
arr.sort()
res = []
# Checking for all possible overlaps
for i in range(n):
start = arr[i][0]
end = arr[i][1]
# Skipping already merged intervals
if res and res[-1][1] >= end:
continue
# Find the end of the merged range
for j in range(i + 1, n):
if arr[j][0] <= end:
end = max(end, arr[j][1])
res.append([start, end])
return res
if __name__ == "__main__":
arr = [[7, 8], [1, 5], [2, 4], [4, 6]]
res = mergeOverlap(arr)
for interval in res:
print(interval[0], interval[1])
C#
using System;
using System.Collections.Generic;
class GfG {
static List<int[]> mergeOverlap(int[][] arr) {
int n = arr.Length;
Array.Sort(arr, (a, b) => a[0].CompareTo(b[0]));
List<int[]> res = new List<int[]>();
// Checking for all possible overlaps
for (int i = 0; i < n; i++) {
int start = arr[i][0];
int end = arr[i][1];
// Skipping already merged intervals
if (res.Count > 0 && res[res.Count - 1][1] >= end)
continue;
// Find the end of the merged range
for (int j = i + 1; j < n; j++) {
if (arr[j][0] <= end)
end = Math.Max(end, arr[j][1]);
}
res.Add(new int[] { start, end });
}
return res;
}
static void Main() {
int[][] arr = new int[][] {
new int[] { 7, 8 },
new int[] { 1, 5 },
new int[] { 2, 4 },
new int[] { 4, 6 }
};
List<int[]> res = mergeOverlap(arr);
foreach (var interval in res)
Console.WriteLine($"{interval[0]} {interval[1]}");
}
}
JavaScript
function mergeOverlap(arr) {
let n = arr.length;
arr.sort((a, b) => a[0] - b[0]);
let res = [];
// Checking for all possible overlaps
for (let i = 0; i < n; i++) {
let start = arr[i][0];
let end = arr[i][1];
// Skipping already merged intervals
if (res.length > 0 && res[res.length - 1][1] >= end) {
continue;
}
// Find the end of the merged range
for (let j = i + 1; j < n; j++) {
if (arr[j][0] <= end) {
end = Math.max(end, arr[j][1]);
}
}
res.push([start, end]);
}
return res;
}
const arr = [[7, 8], [1, 5], [2, 4], [4, 6]];
const res = mergeOverlap(arr);
for (const interval of res)
console.log(interval[0], interval[1]);
[Expected Approach] Checking Last Merged Interval – O(n*log(n)) Time and O(n) Space
In the previous approach, for each range we are checking for possible overlaps by iterating over all the remaining ranges till the end. We can optimize this by checking only those intervals that overlap with the last merged interval. Since the intervals will be sorted based on starting point, so if we encounter an interval whose starting time lies outside the last merged interval, then all further intervals will also lie outside it.
The intuition is to first sort the intervals based on their starting points. This allows us to easily identify overlapping intervals by comparing each interval with the last merged interval. Now, iterate over each interval and if the current interval overlaps with the last merged interval, then merge them both. Otherwise, append the merged interval to the result.
C++
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> mergeOverlap(vector<vector<int>>& arr) {
// Sort intervals based on start values
sort(arr.begin(), arr.end());
vector<vector<int>> res;
res.push_back(arr[0]);
for (int i = 1; i < arr.size(); i++) {
vector<int>& last = res.back();
vector<int>& curr = arr[i];
// If current interval overlaps with the last merged
// interval, merge them
if (curr[0] <= last[1])
last[1] = max(last[1], curr[1]);
else
res.push_back(curr);
}
return res;
}
int main() {
vector<vector<int>> arr = {{7, 8}, {1, 5}, {2, 4}, {4, 6}};
vector<vector<int>> res = mergeOverlap(arr);
for (vector<int>& interval: res)
cout << interval[0] << " " << interval[1] << endl;
return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
class GfG {
static ArrayList<int[]> mergeOverlap(int[][] arr) {
// Sort intervals based on start values
Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
ArrayList<int[]> res = new ArrayList<>();
res.add(new int[]{arr[0][0], arr[0][1]});
for (int i = 1; i < arr.length; i++) {
int[] last = res.get(res.size() - 1);
int[] curr = arr[i];
// If current interval overlaps with the last merged interval,
// merge them
if (curr[0] <= last[1])
last[1] = Math.max(last[1], curr[1]);
else
res.add(new int[]{curr[0], curr[1]});
}
return res;
}
public static void main(String[] args) {
int[][] arr = {{7, 8}, {1, 5}, {2, 4}, {4, 6}};
ArrayList<int[]> res = mergeOverlap(arr);
for (int[] interval : res)
System.out.println(interval[0] + " " + interval[1]);
}
}
Python
def mergeOverlap(arr):
# Sort intervals based on start values
arr.sort()
res = []
res.append(arr[0])
for i in range(1, len(arr)):
last = res[-1]
curr = arr[i]
# If current interval overlaps with the last merged
# interval, merge them
if curr[0] <= last[1]:
last[1] = max(last[1], curr[1])
else:
res.append(curr)
return res
if __name__ == "__main__":
arr = [[7, 8], [1, 5], [2, 4], [4, 6]]
res = mergeOverlap(arr)
for interval in res:
print(interval[0], interval[1])
C#
using System;
using System.Collections.Generic;
class GfG {
// Merge overlapping intervals and return merged intervals as List<int[]>
static List<int[]> mergeOverlap(List<List<int>> arr) {
// Sort intervals based on start values
arr.Sort((a, b) => a[0].CompareTo(b[0]));
List<int[]> res = new List<int[]>();
res.Add(new int[] { arr[0][0], arr[0][1] });
for (int i = 1; i < arr.Count; i++) {
int[] last = res[res.Count - 1];
List<int> curr = arr[i];
// If current interval overlaps with last, merge them
if (last[1] >= curr[0]) {
last[1] = Math.Max(last[1], curr[1]);
} else {
res.Add(new int[] { curr[0], curr[1] });
}
}
return res;
}
static void Main() {
List<List<int>> arr = new List<List<int>> {
new List<int> {7, 8},
new List<int> {1, 5},
new List<int> {2, 4},
new List<int> {4, 6}
};
// Get merged intervals
List<int[]> merged = mergeOverlap(arr);
// Print merged intervals
foreach (int[] interval in merged) {
Console.WriteLine(interval[0] + " " + interval[1]);
}
}
}
JavaScript
function mergeOverlap(arr) {
if (arr.length === 0) return [];
// Sort intervals based on start values
const sorted = [...arr].sort((a, b) => a[0] - b[0]);
const res = [];
res.push(sorted[0]);
for (let i = 1; i < sorted.length; i++) {
const last = res[res.length - 1];
const curr = sorted[i];
// If current interval overlaps with last, merge them
if (curr[0] <= last[1]) {
last[1] = Math.max(last[1], curr[1]);
} else {
res.push(curr);
}
}
return res;
}
// Driver Code
const arr = [[7, 8], [1, 5], [2, 4], [4, 6]];
const res = mergeOverlap(arr);
for (const interval of res) {
console.log(interval[0] + " " + interval[1]);
}
Similar Reads
Non-Overlapping Intervals Given a list of intervals with starting and ending values, the task is to find the minimum number of intervals that are required to be removed to make remaining intervals non-overlapping. Examples:Input: intervals[][] = [[1, 2], [2, 3], [3, 4], [1, 3]]Output: 1 Explanation: Removal of [1, 3] makes t
9 min read
Non-Overlapping Intervals Given a list of intervals with starting and ending values, the task is to find the minimum number of intervals that are required to be removed to make remaining intervals non-overlapping. Examples:Input: intervals[][] = [[1, 2], [2, 3], [3, 4], [1, 3]]Output: 1 Explanation: Removal of [1, 3] makes t
9 min read
Non-Overlapping Intervals Given a list of intervals with starting and ending values, the task is to find the minimum number of intervals that are required to be removed to make remaining intervals non-overlapping. Examples:Input: intervals[][] = [[1, 2], [2, 3], [3, 4], [1, 3]]Output: 1 Explanation: Removal of [1, 3] makes t
9 min read
Maximum number of overlapping Intervals 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 (betw
12 min read
Maximum number of overlapping Intervals 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 (betw
12 min read
Non-overlapping intervals in an array Given a 2d array arr[][] of time intervals, where each interval is of the form [start, end]. The task is to determine all intervals from the given array that do not overlap with any other interval in the set. If no such interval exists, return an empty list.Examples: Input: arr[] = [[1, 3], [2, 4],
4 min read