Maximal Disjoint Intervals (original) (raw)

Last Updated : 11 Jul, 2025

Given a **2D array **arr[][] of order **nx2, representing n **intervals with **start and **end points, the task is to find the **maximal set of mutually **disjoint intervals

**Note: Two intervals **[i, j] & **[k, l] are said to be disjoint if they do not have any point in common.

**Examples:

**Input: arr[][] = [[1, 4], [2, 3], [4, 6], [8, 9]]
**Output:
2 3
4 6
8 9
**Explanation: if [1, 4] is included then we cannot include [2, 3] & [4, 6].

**Input: arr[][] = [[1, 9], [2, 3], [5, 7]]
**Output:
2 3
5 7

Try It Yourselfredirect icon

This problem is mainly a variation of Activity Selection Problem.

[Naive Approach] Generate All Subsets - O(n^2 * 2^n) Time and O(n) Space

  1. Generate all subsets of the given set of intervals.
  2. Check if a subset contains only mutually disjoint intervals by comparing start and end times.
  3. Keep track of the largest valid subset. C++ `

#include #include using namespace std;

// Function to check if a subs // of intervals is mutually disjoint bool isDisj(vector<vector> &subs) { int n = subs.size(); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) {

        // If there is any overlapping
        if (subs[i][1] > subs[j][0] &&
            subs[i][0] < subs[j][1])
            return false; 
    }
}
return true;

}

// Function to find the maximal set of mutually // disjoint intervals vector<vector> maxDisj(vector<vector> &arr) { int n = arr.size(); vector<vector> res;

// Generate all subsets using bitmasking
int subCnt = (1 << n);
for (int mask = 0; mask < subCnt; mask++) {
    vector<vector<int>> subs;

    // Form subs based on mask bits
    for (int i = 0; i < n; i++) {
        if (mask & (1 << i)) {
            subs.push_back(arr[i]);
        }
    }

    // Check if the subs is disjoint
    if (isDisj(subs) && subs.size() > res.size()) {
        res = subs; 
    }
}

return res;

}

// Driver code int main() { vector<vector> arr = {{1, 4}, {2, 3}, {4, 6}, {8, 9}}; vector<vector> result = maxDisj(arr);

for (auto &interval : result) {
    cout << interval[0] << " " << interval[1] << endl;
}

return 0;

}

Java

// Function to check if a subset of intervals // is mutually disjoint public static boolean isDisj(int[][] subs) { int n = subs.length; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) {

        // If there is any overlapping
        if (subs[i][1] > subs[j][0] && 
            subs[i][0] < subs[j][1]) {
            return false;
        }
    }
}
return true;

}

// Function to find the maximal set of mutually // disjoint intervals public static int[][] maxDisj(int[][] arr) { int n = arr.length; List<int[]> res = new ArrayList<>();

// Generate all subsets using bitmasking
int subCnt = 1 << n;
for (int mask = 0; mask < subCnt; mask++) {
    List<int[]> subs = new ArrayList<>();

    // Form subs based on mask bits
    for (int i = 0; i < n; i++) {
        if ((mask & (1 << i)) != 0) {
            subs.add(arr[i]);
        }
    }

    // Check if the subs is disjoint
    if (isDisj(subs.toArray(new int[subs.size()][])) && subs.size() > res.size()) {
        res = subs;
    }
}

return res.toArray(new int[res.size()][]);

}

// Driver code int[][] arr = new int[][] { { 1, 4 }, { 2, 3 }, { 4, 6 }, { 8, 9 } }; int[][] result = maxDisj(arr);

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

Python

Function to check if a subs

of intervals is mutually disjoint

def is_disj(subs): n = len(subs) for i in range(n): for j in range(i + 1, n): # If there is any overlapping if subs[i][1] > subs[j][0] and subs[i][0] < subs[j][1]: return False return True

Function to find the maximal set of mutually

disjoint intervals

def max_disj(arr): n = len(arr) res = []

# Generate all subsets using bitmasking
sub_cnt = 1 << n
for mask in range(sub_cnt):
    subs = []

    # Form subs based on mask bits
    for i in range(n):
        if mask & (1 << i):
            subs.append(arr[i])

    # Check if the subs is disjoint
    if is_disj(subs) and len(subs) > len(res):
        res = subs

return res

Driver code

arr = [[1, 4], [2, 3], [4, 6], [8, 9]] result = max_disj(arr)

for interval in result: print(interval[0], interval[1])

C#

// Function to check if a subset of intervals is mutually disjoint public static bool IsDisj(int[,] subs) { int n = subs.GetLength(0); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { // If there is any overlapping if (subs[i, 1] > subs[j, 0] && subs[i, 0] < subs[j, 1]) { return false; } } } return true; }

// Function to find the maximal set of // mutually disjoint intervals public static List<int[]> MaxDisj(int[,] arr) { int n = arr.GetLength(0); List<int[]> res = new List<int[]>();

// Generate all subsets using bitmasking
int subCnt = 1 << n;
for (int mask = 0; mask < subCnt; mask++)
{
    List<int[]> subs = new List<int[]>();

    // Form subs based on mask bits
    for (int i = 0; i < n; i++)
    {
        if ((mask & (1 << i)) != 0)
        {
            subs.Add(new int[] { arr[i, 0], arr[i, 1] });
        }
    }

    // Check if the subs is disjoint
    if (IsDisj(arr) && subs.Count > res.Count)
    {
        res = subs;
    }
}

return res;

}

// Driver code int[,] arr = new int[,] { { 1, 4 }, { 2, 3 }, { 4, 6 }, { 8, 9 } }; List<int[]> result = MaxDisj(arr);

foreach (var interval in result) { Console.WriteLine(interval[0] + " " + interval[1]); }

JavaScript

// Function to check if a subs // of intervals is mutually disjoint function isDisj(subs) { let n = subs.length; for (let i = 0; i < n; i++) { for (let j = i + 1; j < n; j++) { // If there is any overlapping if (subs[i][1] > subs[j][0] && subs[i][0] < subs[j][1]) return false; } } return true; }

// Function to find the maximal set of mutually // disjoint intervals function maxDisj(arr) { let n = arr.length; let res = [];

// Generate all subsets using bitmasking
let subCnt = 1 << n;
for (let mask = 0; mask < subCnt; mask++) {
    let subs = [];

    // Form subs based on mask bits
    for (let i = 0; i < n; i++) {
        if (mask & (1 << i)) {
            subs.push(arr[i]);
        }
    }

    // Check if the subs is disjoint
    if (isDisj(subs) && subs.length > res.length) {
        res = subs;
    }
}

return res;

}

// Driver code let arr = [[1, 4], [2, 3], [4, 6], [8, 9]]; let result = maxDisj(arr);

for (let interval of result) { console.log(interval[0], interval[1]); }

`

**[Expected Approach] Using Greedy Approach - O(n*log(n)) Time and O(1) Space.

The idea is to include the intervals with **smallest **end points as it will allow to include most of the other intervals. To do so, first **sort the given array arr[][] **based on their **end points. Create a 2d array **res[][] to **store set of intervals and a counter **end, initialized with **-1, it will **store the **end point of **last included **interval. For each index i, check if start point of arr[i] i.e. **arr[i][0] is greater than **end, if so, **add current element in **res[] and **update **end to **end point of arr[i] i.e. **arr[i][1], **else skip the element.

C++ `

#include <bits/stdc++.h> using namespace std;

bool comp(const vector &a, const vector &b) { return (a[1] < b[1]); }

// Function to find maximal disjoint set vector<vector> getDisjoint(vector<vector> &arr) {

// Sort the array of intervals
// based on second element
sort(arr.begin(), arr.end(), comp);

// Stores the end point of the last
// interval included in the maximal
int end = -1;

// Stores the maximal disjoint set
vector<vector<int>> ans;

for (int i = 0; i < arr.size(); i++)
{

    if (arr[i][0] > end)
    {
        ans.push_back(arr[i]);
        end = arr[i][1];
    }
}

return ans;

}

// Driver code int main() { vector<vector> arr = {{1, 4}, {2, 3}, {4, 6}, {8, 9}}; vector<vector> ans = getDisjoint(arr); for (int i = 0; i < ans.size(); i++) { cout << ans[i][0] << " " << ans[i][1] << endl; } return 0; }

Java

import java.util.Arrays;

class GfG {

// Function to find maximal disjoint set without using a
// list
static int[][] getDisjoint(int[][] arr)
{
    // Sort the intervals based on end time
    Arrays.sort(arr,
                (a, b) -> Integer.compare(a[1], b[1]));

    // Count the maximum number of disjoint intervals
    int count = 0;
    int end = -1;

    // First, determine the size of the result array
    for (int i = 0; i < arr.length; i++) {
        if (arr[i][0] > end) {
            count++;
            end = arr[i][1];
        }
    }

    // Create an array of appropriate size
    int[][] result = new int[count][2];
    end = -1;
    int index = 0;

    // Fill the result array with disjoint intervals
    for (int i = 0; i < arr.length; i++) {
        if (arr[i][0] > end) {
            result[index][0] = arr[i][0];
            result[index][1] = arr[i][1];
            index++;
            end = arr[i][1];
        }
    }

    return result;
}

// Driver code
public static void main(String[] args)
{
    int[][] arr
        = { { 1, 4 }, { 2, 3 }, { 4, 6 }, { 8, 9 } };

    // Call getDisjoint function
    int[][] ans = getDisjoint(arr);

    // Print the maximal disjoint intervals
    for (int i = 0; i < ans.length; i++) {
        System.out.println(ans[i][0] + " " + ans[i][1]);
    }
}

}

Python

def getDisjoint(arr):

# Sort the array of intervals
# based on second element
arr.sort(key=lambda x: x[1])

# Stores the end point of the last
# interval included in the maximal
end = -1

# Stores the maximal disjoint set
ans = []

for i in range(len(arr)):

    # If the current interval has
    # start point greater than the
    # end point of the last interval
    if arr[i][0] > end:
        ans.append(arr[i])
        end = arr[i][1]

return ans

Driver code

if name == "main": arr = [ [1, 4], [2, 3], [4, 6], [8, 9] ] ans = getDisjoint(arr) for interval in ans: print(interval[0], interval[1])

C#

using System;

class GfG { // Function to find maximal disjoint set without using a List static int[,] getDisjoint(int[,] arr) { int n = arr.GetLength(0);

    // Convert 2D array to 1D array of intervals for sorting
    int[][] intervals = new int[n][];
    for (int i = 0; i < n; i++)
        intervals[i] = new int[] { arr[i, 0], arr[i, 1] };

    // Sort intervals based on end time
    Array.Sort(intervals, (a, b) => a[1].CompareTo(b[1]));

    // Count the number of disjoint intervals
    int count = 0, end = -1;

    for (int i = 0; i < n; i++)
    {
        if (intervals[i][0] > end)
        {
            count++;
            end = intervals[i][1];
        }
    }

    // Create a fixed-size array to store the result
    int[,] result = new int[count, 2];
    end = -1;
    int index = 0;

    // Fill the result array with disjoint intervals
    for (int i = 0; i < n; i++)
    {
        if (intervals[i][0] > end)
        {
            result[index, 0] = intervals[i][0];
            result[index, 1] = intervals[i][1];
            index++;
            end = intervals[i][1];
        }
    }

    return result;
}

// Driver code
static void Main(string[] args)
{
    int[,] arr = { { 1, 4 }, { 2, 3 }, { 4, 6 }, { 8, 9 } };

    // Call getDisjoint function
    int[,] ans = getDisjoint(arr);

    // Print the maximal disjoint intervals
    for (int i = 0; i < ans.GetLength(0); i++)
    {
        Console.WriteLine(ans[i, 0] + " " + ans[i, 1]);
    }
}

}

JavaScript

function getDisjoint(arr) {

// Sort the array of intervals
// based on second element
arr.sort((a, b) => a[1] - b[1]);

// Stores the end point of the last
// interval included in the maximal
let end = -1;

// Stores the maximal disjoint set
let ans = [];

for (let i = 0; i < arr.length; i++) {

    if (arr[i][0] > end) {
        ans.push(arr[i]);
        end = arr[i][1];
    }
}

return ans;

}

let arr = [ [ 1, 4 ], [ 2, 3 ], [ 4, 6 ], [ 8, 9 ] ]; let ans = getDisjoint(arr); ans.forEach( interval => { console.log(interval[0], interval[1]); });

`