Merge Overlapping Intervals

Spread the love

The challenge is to combine all the overlapping intervals into one and produce the output which should include only mutually exclusive intervals given an array of time intervals whereby arr[i] = [starti, endi].

As an illustration,:

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].

Table of Content

[Naive Approach] Checking All Possible Overlaps – O(n^2) Time and O(1) Space

One might start from the first interval and compare it with every other interval for overlaps by first grouping all the intervals and then. Eliminate the other interval from the list and combine the other into the first interval if the first interval crosses any other interval. Proceed similarly for the next intervals following the first.

C++

// C++ Code to Merge Overlapping Intervals by Checking
// All Possible Overlaps

#include <algorithm>
#include <iostream>
#include <vector>
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

// Java Code to Merge Overlapping Intervals by Checking
// All Possible Overlaps

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class GfG {

    static List<int[]> mergeOverlap(int[][] arr) {
        int n = arr.length;

        Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
        List<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}};
        List<int[]> res = mergeOverlap(arr);

        for (int[] interval : res) {
            System.out.println(interval[0] + " " + interval[1]);
        }
    }
}

Python

# Python Code to Merge Overlapping Intervals by Checking
# All Possible Overlaps

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#

// C# Code to Merge Overlapping Intervals by Checking
// All Possible Overlaps

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

// JavaScript Code to Merge Overlapping Intervals by Checking
// All Possible Overlaps

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]);

Output

1 6
7 8