其他分享
首页 > 其他分享> > 435. 无重叠区间

435. 无重叠区间

作者:互联网

435. 无重叠区间

原始题目链接:https://leetcode-cn.com/problems/non-overlapping-intervals/

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

注意:

可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:

输入: [ [1,2], [2,3], [3,4], [1,3] ]

输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:

输入: [ [1,2], [1,2], [1,2] ]

输出: 2

解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:

输入: [ [1,2], [2,3] ]

输出: 0

解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

解题思路:

这道题需要计算移除交叉区间的个数,可以转换为总的区间个数减去非交叉区间的个数,所以最后是计算非交叉区间的个数即可。交叉和非交叉要看区间的值即左边界和右边界,这就需要排序来判断看看两个边界是否有重复的,针对右边界排序的话,就需要从左到右进行遍历整个数组来计算非交叉的,为了找到非交叉的区间,尽量选择右边界小的数字,这样留个下一个区间更大的选择空间,做到局部最优,通过局部最优推出全局最优,这就用到了贪心的思想。具体实现看代码及注释。

代码实现:

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0

        # 对数组中的第二个元素即右区间进行排序
        intervals.sort(key = lambda x: x[1])
        # 非交叉区间计数器
        count = 1
        n = len(intervals)

        # 排序好的intervals从左到右寻找非交叉区间
        # 需要维护一个右侧区间的值,每次和遍历区间数组的左区间进行比较
        # 看数组的左区间是否大于等于上一个非交叉的右侧区间,大于等等于的话
        # 说明是非交叉的,并且用当前数组的右区间更新right的值用于下次的比较,小于的话说明是重叠的
        # right的初始值是排还序的intervals的第一个元素的右区间的值
        right = intervals[0][1]
        
        for i in range(1, n):
            if intervals[i][0] >= right:
                right = intervals[i][1]
                count += 1
        
        # 数组中区间的总数减去非交叉区间的个数就是题目中需要返回的移除区间的最小数量
        return n - count

参考文献:
https://leetcode-cn.com/problems/non-overlapping-intervals/solution/435-wu-zhong-die-qu-jian-tan-xin-jing-di-qze0/

标签:right,重叠,交叉,intervals,移除,区间,435
来源: https://blog.csdn.net/u013243296/article/details/121071701