Given an array intervals
where intervals[i] = [li, ri]
represent the interval [li, ri)
, remove all intervals that are covered by another interval in the list.
The interval [a, b)
is covered by the interval [c, d)
if and only if c <= a
and b <= d
.
Return the number of remaining intervals.
Example 1:
Input: intervals = [[1,4],[3,6],[2,8]] Output: 2 Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
Example 2:
Input: intervals = [[1,4],[2,3]] Output: 1
Constraints:
1 <= intervals.length <= 1000
intervals[i].length == 2
0 <= li < ri <= 105
This problem asks to find the number of intervals that are not covered by any other interval in a given list of intervals. The key insight is that we can sort the intervals cleverly to efficiently identify covered intervals.
Approach:
Sorting: We sort the intervals based on their start times. If two intervals have the same start time, we prioritize the one with the smaller end time. This is crucial for the efficiency of the algorithm. The sorting ensures that we process intervals in increasing order of their start times.
Iteration and Comparison: We iterate through the sorted intervals, keeping track of the interval with the largest end time encountered so far (pre
). For each new interval, we compare its end time to the end time of pre
.
pre
's end time, it means this interval is not covered by pre
(or any previous interval). We increment our counter of uncovered intervals and update pre
to this current interval.pre
(or potentially an even earlier interval) and we ignore it.Return Value: The final count of uncovered intervals is returned.
Time Complexity Analysis:
Space Complexity Analysis:
pre
variable and the counter.Code Explanation (Python):
class Solution:
def removeCoveredIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: (x[0], -x[1])) #Sort by start time, then descending end time.
cnt, pre = 1, intervals[0] # Initialize count and 'previous' interval
for e in intervals[1:]: #Iterate through remaining intervals
if pre[1] < e[1]: #Check if current interval's end is greater than previous
cnt += 1 #Increment count if not covered
pre = e #Update previous interval
return cnt
The lambda
function used in intervals.sort()
defines a custom sorting key. It prioritizes sorting by the first element (start time) and then uses the negative of the second element (end time) for secondary sorting in descending order. This ensures that intervals with the same start time are ordered such that the one with the largest end time comes first.
The rest of the Python code directly implements the algorithm explained above. The Java, C++, and Go code follow the same approach, only differing in syntax. The core logic of sorting and comparing end times remains consistent across all languages.