Minimum removals required to make ranges non-overlapping
Given a list of ranges with starting and end value, the task is to find the minimum number of ranges that are required to be removed to make remaining ranges non-overlapping. Examples:
Input : input = {{1, 2}, {4, 7}, {3, 8}} Output : 1 Explanation: Removal of {3, 8} makes {{1, 2} and {4, 7}} non-overlapping. Input : input = {{ 10, 20 }, { 10, 20 } , { 10, 20 }} Output : 2 Explanation: Removal of [10, 20] makes the remaining ranges non-overlapping. Input : input = {{1, 2}, {5, 10}, {18, 35}, {40, 45}} Output : 0 Explanation:All ranges are already non-overlapping.
Approach 1 : (Sort basis on Starting Values)
- Sort the ranges by their starting values.
- Traverse through the ranges and check if any range has a starting point less than the ending point of the previous (ie. there is an overlap).
- Remove the range with greater ending point.
Below code is the implementation of the above approach:
#include <bits/stdc++.h>
using namespace std;
int minRemovals(vector<vector<int> >& ranges)
{
int size = ranges.size(), rem = 0;
if (size <= 1)
return 0;
// Sort by minimum starting point
sort(ranges.begin(), ranges.end(),
[](const vector<int>& a, const vector<int>& b)
{ return a[0] < b[0]; });
int end = ranges[0][1];
for (int i = 1; i < ranges.size(); i++) {
// If the current starting point is less than
// the previous interval's ending point
// (ie. there is an overlap)
if (ranges[i][0] < end) {
// increase rem
rem++;
// Remove the interval
// with the higher ending point
end = min(ranges[i][1], end);
}
else
end = ranges[i][1];
}
return rem;
}
// Driver code
int main()
{
vector<vector<int> > input = { { 19, 25 },
{ 10, 20 }, { 16, 20 } };
cout << minRemovals(input) << endl;
}
//Java equivalent of above code
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static int minRemovals(List<int[]> ranges) {
int size = ranges.size(), rem = 0;
if (size <= 1)
return 0;
// Sort by minimum starting point
Collections.sort(ranges, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
int end = ranges.get(0)[1];
for (int i = 1; i < ranges.size(); i++) {
// If the current starting point is less than
// the previous interval's ending point
// (ie. there is an overlap)
if (ranges.get(i)[0] < end) {
// increase rem
rem++;
// Remove the interval
// with the higher ending point
end = Math.min(ranges.get(i)[1], end);
} else
end = ranges.get(i)[1];
}
return rem;
}
// Driver code
public static void main(String[] args) {
List<int[]> input = new ArrayList<int[]>();
input.add(new int[] { 19, 25 });
input.add(new int[] { 10, 20 });
input.add(new int[] { 16, 20 });
System.out.println(minRemovals(input));
}
}
def minRemovels (ranges):
size = len(ranges)
rem = 0
# Sort by minimum starting point
ranges.sort()
end = ranges[0][1]
for i in range(1, size):
# If the current starting point is less
# than the previous interval's ending
# point (ie. there is an overlap)
if (ranges[i][0] < end):
# Increase rem
rem += 1
# Remove the interval
# with the higher ending point
end = min(ranges[i][1], end)
else:
end = ranges[i][1]
return rem
# Driver Code
if __name__ == '__main__':
Input = [ [ 19, 25 ],
[ 10, 20 ],
[ 16, 20 ] ]
print(minRemovels(Input))
# This code is contributed by himanshu77
using System;
using System.Linq;
class GFG {
static int MinRemovals(int[][] ranges)
{
int size = ranges.Length;
int rem = 0;
// Sort by minimum starting point
Array.Sort(ranges, (a, b) => a[0] - b[0]);
int end = ranges[0][1];
for (int i = 1; i < size; i++)
{
// If the current starting point is less than
// the previous interval's ending point (ie.
// there is an overlap)
if (ranges[i][0] < end)
{
// Increase rem
rem += 1;
// Remove the interval with the higher
// ending point
end = Math.Min(ranges[i][1], end);
}
else {
end = ranges[i][1];
}
}
return rem;
}
// Driver code
public static void Main(string[] args)
{
int[][] ranges
= new int[][] { new int[] { 19, 25 },
new int[] { 10, 20 },
new int[] { 16, 20 } };
// Function call
Console.WriteLine(MinRemovals(ranges));
}
}
// This code is contributed by phasing17
// JavaScript implementation to find the minimum
// removals required to make intervals non-overlapping
function minRemovels(ranges) {
var size = ranges.length;
var rem = 0;
// Sort by minimum starting point
ranges.sort(function(a, b) {
return a[0] - b[0];
});
var end = ranges[0][1];
for (var i = 1; i < size; i++) {
// If the current starting point is less than the previous interval's ending
// point (ie. there is an overlap)
if (ranges[i][0] < end) {
// Increase rem
rem += 1;
// Remove the interval with the higher ending point
end = Math.min(ranges[i][1], end);
} else {
end = ranges[i][1];
}
}
return rem;
}
// Driver Code
var ranges = [[19, 25], [10, 20], [16, 20]];
console.log(minRemovels(ranges));
// This code is contributed by phasing17
Output
2
Time Complexity: O(n log n)
Auxiliary Space: O(1) as no extra space has been used.
Approach 2 : (Sort basis on Ending Values)
- The idea still remains the same as approach 1 as the main work is to find out the overlap point and keep a greater ending time.
- Sort the array on basis of ending values.
- Increase the count (i.e. remove the range with greater end point) if any overlap condition is found.
- else update for a greater end point.
Below is the code for better understanding.
#include <bits/stdc++.h>
using namespace std;
// comparator function
bool comp(vector<int>& v1, vector<int>& v2)
{
return v1[1] < v2[1];
}
int minRemovals(vector<vector<int> >& ranges)
{
int size = ranges.size(), rem = 0;
if (size <= 1)
return 0;
// Sort by minimum ending point
sort(ranges.begin(), ranges.end(), comp);
int end = ranges[0][1];
for (int i = 1; i < ranges.size(); i++) {
// if there is an overlap
// increase the count
if (ranges[i][0] < end)
rem++;
// else increment the ending point
else
end = ranges[i][1];
}
// return the ans
return rem;
}
// Driver code
int main()
{
vector<vector<int> > input
= { { 19, 25 }, { 10, 20 }, { 16, 20 } };
cout << minRemovals(input) << endl;
}
// this code is contributed by Rajdeep Mallick (rajdeep999)
import java.util.*;
class Main {
// Comparator function
static boolean comp(ArrayList<Integer> v1, ArrayList<Integer> v2) {
return v1.get(1) < v2.get(1);
}
static int minRemovals(ArrayList<ArrayList<Integer>> ranges) {
int size = ranges.size(), rem = 0;
if (size <= 1)
return 0;
// Sort by minimum ending point
Collections.sort(ranges, (a, b) -> a.get(1).compareTo(b.get(1)));
int end = ranges.get(0).get(1);
for (int i = 1; i < ranges.size(); i++) {
// if there is an overlap, increase the count
if (ranges.get(i).get(0) < end)
rem++;
// else increment the ending point
else
end = ranges.get(i).get(1);
}
// return the ans
return rem;
}
// Driver code
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> input = new ArrayList<>();
input.add(new ArrayList<>(Arrays.asList(19, 25)));
input.add(new ArrayList<>(Arrays.asList(10, 20)));
input.add(new ArrayList<>(Arrays.asList(16, 20)));
System.out.println(minRemovals(input));
}
}
# Comparator function
def comp(v1, v2):
return v1[1] < v2[1]
def min_removals(ranges):
size = len(ranges)
rem = 0
if size <= 1:
return 0
# Sort by minimum ending point
ranges.sort(key=lambda x: x[1])
end = ranges[0][1]
for i in range(1, len(ranges)):
# If there is an overlap, increase the count
if ranges[i][0] < end:
rem += 1
# Else, increment the ending point
else:
end = ranges[i][1]
# Return the answer
return rem
# Driver code
if __name__ == "__main__":
input_ranges = [[19, 25], [10, 20], [16, 20]]
print(min_removals(input_ranges))
// Comparator function
function comp(v1, v2) {
return v1[1] < v2[1];
}
// Function to calculate the minimum removals
function minRemovals(ranges) {
let size = ranges.length;
let rem = 0;
if (size <= 1)
return 0;
// Sort by minimum ending point
ranges.sort(comp);
let end = ranges[0][1];
for (let i = 1; i < ranges.length; i++) {
// If there is an overlap, increase the count
if (ranges[i][0] < end)
rem++;
// Else, increment the ending point
else
end = ranges[i][1];
}
// Return the result
return rem;
}
// Driver code
function main() {
let input = [[19, 25], [10, 20], [16, 20]];
console.log(minRemovals(input));
}
// Call the main function
main();
Output
2
Time Complexity: O(n log n)
Auxiliary Space: O(1) as no extra space has been used.
Contact Us