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
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
- Generate all subsets of the given set of intervals.
- Check if a subset contains only mutually disjoint intervals by comparing start and end times.
- 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 resDriver 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 ansDriver 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]); });
`