LeetCode: 435.无重叠区间

题目:给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

这道题和合并区间有点类似。但合并区间要求求出合并之后的区间集合。这道题是要你删除最小数量的一些区间,使得剩下的区间不重合。

解法

  • 暴力:我们当然可以遍历所有不重叠的区间组合,然后用删除前总集合数目-剩下的区间数目,就是删除的数目。取最小就行了(超时)

  • 动态规划(超时)。我们先对每个集合的第一个地址排序(一般涉及区间都是先按第一个元素或者第二个元素排序)。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

你可能感兴趣的:(LeetCode)