Non-overlapping Intervals medium
Problem Statement
Given an array of intervals intervals
where intervals[i] = [starti, endi]
, return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
Example 1:
Input: intervals = [[1,2],[2,3],[3,4],[1,3]] Output: 1 Explanation: [1,3] can be removed and the rest of the intervals are non-overlapping.
Example 2:
Input: intervals = [[1,2],[1,2],[1,2]] Output: 2 Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping.
Steps
-
Sort the intervals: Sort the intervals by their end times in ascending order. This ensures that we consider intervals with earlier end times first.
-
Initialize variables: We'll need a variable
lastEnd
to track the end time of the last non-overlapping interval and a variableremovedCount
to count the number of intervals removed. -
Iterate through sorted intervals:
- If the current interval's start time is greater than or equal to the
lastEnd
, it means this interval doesn't overlap with the previous non-overlapping interval. We updatelastEnd
to the current interval's end time. - Otherwise, the current interval overlaps. We increment
removedCount
.
- If the current interval's start time is greater than or equal to the
-
Return the count: After iterating through all intervals,
removedCount
will hold the minimum number of intervals to remove.
Explanation
The algorithm is based on a greedy approach. By sorting the intervals by their end times, we prioritize selecting intervals that end earlier. This allows us to maximize the number of non-overlapping intervals we can keep. If an interval overlaps with the previously selected non-overlapping interval, it's removed to maintain non-overlapping condition. This strategy ensures we find the minimum number of intervals to remove because we are always trying to fit in as many non-overlapping intervals as possible.
Code
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public int EraseOverlapIntervals(int[][] intervals) {
if (intervals == null || intervals.Length == 0) {
return 0;
}
// Sort intervals by end times
Array.Sort(intervals, (a, b) => a[1] - b[1]);
int lastEnd = intervals[0][1];
int removedCount = 0;
for (int i = 1; i < intervals.Length; i++) {
if (intervals[i][0] < lastEnd) {
removedCount++;
} else {
lastEnd = intervals[i][1];
}
}
return removedCount;
}
}
Complexity
- Time Complexity: O(N log N), dominated by the sorting step.
- Space Complexity: O(log N) or O(N), depending on the sorting algorithm used (in-place sorting like quicksort would be O(log N) while merge sort uses O(N) extra space). The rest of the algorithm uses constant extra space.