题目:给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
这道题和合并区间有点类似。但合并区间要求求出合并之后的区间集合。这道题是要你删除最小数量的一些区间,使得剩下的区间不重合。
解法
-
暴力:我们当然可以遍历所有不重叠的区间组合,然后用删除前总集合数目-剩下的区间数目,就是删除的数目。取最小就行了(超时)
-
动态规划(超时)。我们先对每个集合的第一个地址排序(一般涉及区间都是先按第一个元素或者第二个元素排序)。dp[i]记录前i个区间使之不重叠的最小删除区间数目。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
n = len(intervals)
if n ==0 :
return 0
intervals.sort(key=lambda x: x[0])
dp = [0] * n
dp[0] =1
ans = 1
for i in range(1, n):
cur = intervals[i]
temp = 0
for j in range(i):
prev = intervals[j]
if prev[1] >cur[0]: # overlapping
pass
else:
temp = max(temp, dp[j])
dp[i] = temp+1
ans = max(temp+1, ans)
# print(dp)
return n -ans
- 贪心解法: 按照结束时间排序。直观的解释是,优选选择结束时间小的区间,则能为更多其他区间留出空间,能获得最多的不重叠区间数目。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if len(intervals) == 0:
return 0
intervals.sort(key=lambda x: x[1]) # 对结束时间排序
cnt = 0
end = -float('inf')
for i in range(len(intervals)):
if end <= intervals[i][0]: # 不重叠
cnt+=1 # 保留
if end < intervals[i][1]: # 更新当前最大的结束时间
end = intervals[i][1]
return len(intervals) - cnt