Non-overlapping intervals in an array

Last Updated : 14 Jan, 2026

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], [3, 5], [7, 9]] 
Output: [[5, 7]] 
Explanation: The only interval which doesn’t overlaps with the other intervals is [5, 7].

Input: arr[][] = [[1, 3], [2, 6], [8, 10], [15, 18]] 
Output: [[6, 8], [10, 15]]
Explanation: There are two intervals which don’t overlap with other intervals are [6, 8], [10, 15].

Input: arr[][] = [[1, 3], [9, 12], [2, 4], [6, 8]] 
Output: [[4, 6], [8, 9]] 
Explanation: There are two intervals which don’t overlap with other intervals are [4, 6], [8, 9].

Approach:

The idea is to sort the given time intervals according to their starting time and update processedEnd variable after analyzing each interval.

Steps to implement the above idea:

  • Sort the given set of intervals according to their starting time.
  • Initialize processedEnd to arr[0][1].
  • Traverse through all the intervals, If the intervals(say interval processed & interval curr) do not overlap then the pair form by [processedEnd, curr.start] is the non-overlapping interval.
  • Update the processed interval after each comparison.
C++
#include <bits/stdc++.h>
using namespace std;

vector<vector<int>> findGaps(vector<vector<int>> &arr) {
    if (arr.empty()) return {};
    
    // Sort intervals by start time
    sort(arr.begin(), arr.end());
    int processedEnd=arr[0][1];
    vector<vector<int>> res;
    for (int i = 1; i < arr.size(); i++) {
        
        if (processedEnd < arr[i][0]) {
            res.push_back({processedEnd, arr[i][0]});
        }
        processedEnd = max(processedEnd, arr[i][1]);
    }
    return res;
}

int main() {
    vector<vector<int>> arr = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
    
    for (auto &gap : findGaps(arr)) {
        cout << "[" << gap[0] << ", " << gap[1] << "] ";
    }
    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static List<int[]> findGaps(int[][] arr) {
        if (arr.length == 0) {
            return new ArrayList<>();
        }
        
        // Sort intervals by start time
        Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
        
        int processedEnd = arr[0][1];
        List<int[]> res = new ArrayList<>();
        for (int i = 1; i < arr.length; i++) {
            
            if (processedEnd < arr[i][0]) {
                res.add(new int[]{processedEnd, arr[i][0]});
            }
            processedEnd = Math.max(processedEnd, arr[i][1]);
        }
        return res;
    }
    
    public static void main(String[] args) {
        int[][] arr = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};
        
        for (int[] gap : findGaps(arr)) {
            System.out.print("[" + gap[0] + ", " + gap[1] + "] ");
        }
    }
}
Python
def find_gaps(arr):
    if not arr:
        return []
    
    # Sort intervals by start time
    arr.sort()
    processed_end = arr[0][1]
    res = []
    for i in range(1, len(arr)):
        
        if processed_end < arr[i][0]:
            res.append([processed_end, arr[i][0]])
            
        processed_end = max(processed_end, arr[i][1])
            
    return res

if __name__ == '__main__':
    arr = [[1, 3], [2, 6], [8, 10], [15, 18]]
    
    for gap in find_gaps(arr):
        print(f'[{gap[0]}, {gap[1]}]', end=' ')
C#
using System;
using System.Collections.Generic;
using System.Linq;

public class MainClass {
    public static List<int[]> FindGaps(int[][] arr) {
        if (arr.Length == 0) {
            return new List<int[]>();
        }
        
        // Sort intervals by start time
        Array.Sort(arr, (a, b) => a[0].CompareTo(b[0]));
        int processedEnd = arr[0][1];
        List<int[]> res = new List<int[]>();
        for (int i = 1; i < arr.Length; i++) {
            
            if (processedEnd < arr[i][0]) {
                res.Add(new int[] { processedEnd, arr[i][0] });
            }
            processedEnd = Math.Max(processedEnd, arr[i][1]);
        }
        return res;
    }
    
    public static void Main(string[] args) {
        int[][] arr = new int[][] { new int[] { 1, 3 }, new int[] { 2, 6 }, new int[] { 8, 10 }, new int[] { 15, 18 } };
        
        foreach (int[] gap in FindGaps(arr)) {
            Console.Write("[" + gap[0] + ", " + gap[1] + "] ");
        }
    }
}
JavaScript
function findGaps(arr) {
    if (arr.length === 0) {
        return [];
    }
    
    // Sort intervals by start time
    arr.sort((a, b) => a[0] - b[0]);
    let processedEnd = arr[0][1];
    const res = [];
    for (let i = 1; i < arr.length; i++) {
        
        if (processedEnd < arr[i][0]) {
            res.push([processedEnd, arr[i][0]]);
        }
        processedEnd = Math.max(processedEnd, arr[i][1]);
    }
    return res;
}

const arr = [[1, 3], [2, 6], [8, 10], [15, 18]];

for (const gap of findGaps(arr)) {
    console.log(`[${gap[0]}, ${gap[1]}]`);
}

Output
[6, 8] [10, 15] 

Time Complexity: O(n*log(n)), where n is the number of set of intervals.
Auxiliary Space: O(n)
 

Comment