435. Non-overlapping Intervals
Problem Description
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 the intervals non-overlapping.
Example 3:
Input: intervals = [[1,2],[2,3]]
Output: 0
Explanation: You don't need to remove any of the intervals since they're already non-overlapping.
Constraints:
1 <= intervals.length <= 10⁵intervals[i].length == 2-5 * 10⁴ <= starti < endi <= 5 * 10⁴
Solution
Python Solution
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
# Sort intervals by end time
intervals.sort(key=lambda x: x[1])
non_overlapping = 1
end = intervals[0][1]
# Count non-overlapping intervals
for i in range(1, len(intervals)):
if intervals[i][0] >= end:
non_overlapping += 1
end = intervals[i][1]
return len(intervals) - non_overlapping
Time Complexity: O(n log n)
Where n is the number of intervals. The sorting step takes O(n log n) time.
Space Complexity: O(1)
Only using a constant amount of extra space.
Java Solution
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals == null || intervals.length == 0) {
return 0;
}
// Sort intervals by end time
Arrays.sort(intervals, (a, b) -> Integer.compare(a[1], b[1]));
int nonOverlapping = 1;
int end = intervals[0][1];
// Count non-overlapping intervals
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] >= end) {
nonOverlapping++;
end = intervals[i][1];
}
}
return intervals.length - nonOverlapping;
}
}
Time Complexity: O(n log n)
Where n is the number of intervals. The sorting step takes O(n log n) time.
Space Complexity: O(1)
Only using a constant amount of extra space.
C++ Solution
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
if (intervals.empty()) {
return 0;
}
// Sort intervals by end time
sort(intervals.begin(), intervals.end(),
[](const vector& a, const vector& b) {
return a[1] < b[1];
});
int nonOverlapping = 1;
int end = intervals[0][1];
// Count non-overlapping intervals
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] >= end) {
nonOverlapping++;
end = intervals[i][1];
}
}
return intervals.size() - nonOverlapping;
}
};
Time Complexity: O(n log n)
Where n is the number of intervals. The sorting step takes O(n log n) time.
Space Complexity: O(1)
Only using a constant amount of extra space.
JavaScript Solution
/**
* @param {number[][]} intervals
* @return {number}
*/
var eraseOverlapIntervals = function(intervals) {
if (!intervals.length) {
return 0;
}
// Sort intervals by end time
intervals.sort((a, b) => a[1] - b[1]);
let nonOverlapping = 1;
let end = intervals[0][1];
// Count non-overlapping intervals
for (let i = 1; i < intervals.length; i++) {
if (intervals[i][0] >= end) {
nonOverlapping++;
end = intervals[i][1];
}
}
return intervals.length - nonOverlapping;
};
Time Complexity: O(n log n)
Where n is the number of intervals. The sorting step takes O(n log n) time.
Space Complexity: O(1)
Only using a constant amount of extra space.
C# Solution
public class Solution {
public int EraseOverlapIntervals(int[][] intervals) {
if (intervals == null || intervals.Length == 0) {
return 0;
}
// Sort intervals by end time
Array.Sort(intervals, (a, b) => a[1].CompareTo(b[1]));
int nonOverlapping = 1;
int end = intervals[0][1];
// Count non-overlapping intervals
for (int i = 1; i < intervals.Length; i++) {
if (intervals[i][0] >= end) {
nonOverlapping++;
end = intervals[i][1];
}
}
return intervals.Length - nonOverlapping;
}
}
Time Complexity: O(n log n)
Where n is the number of intervals. The sorting step takes O(n log n) time.
Space Complexity: O(1)
Only using a constant amount of extra space.
Approach Explanation
The solution uses a greedy approach:
- Key Insights:
- Sort by end time
- Greedy selection
- Interval tracking
- Overlap detection
- Algorithm Steps:
- Sort intervals
- Track end time
- Count non-overlapping
- Calculate removals
Implementation Details:
- Sorting logic
- Interval comparison
- Counter management
- Result calculation
Optimization Insights:
- End time sorting
- Single pass
- Early termination
- Space efficiency
Edge Cases:
- Empty array
- Single interval
- Complete overlap
- No overlap