【贪心】leetcode435.无重叠区间

461 篇文章 1 订阅

题目:
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
在这里插入图片描述

思路:
贪心算法:
将所有区间按右端点进行排序,并将第一个区间作为符合条件的初始区间,并记其右端点为right,则按序查找首个 左端点大于等于right的区间,令其为第二个区间。依次类推,直到所有区间遍历完毕。

证明:最优子结构
若存在两个区间,区间i [li,ri] 和区间j [lj,rj]。设区间j是首个(最左侧)区间,左侧没有不重叠的区间,右侧有若干个不重叠的区间。若存在一个区间i,其右侧端点值ri 小于 区间j的右侧端点值rj,则将区间j换位区间i,仍然满足条件。所以我们可以得到,首个区间就是所有可以选择的区间中右端点最小的那个区间。当确定了首个区间之后,所有与首个区间不重合的区间就组成了一个规模更小的子问题。

解答:

方法一:按右边界排序,从左到右进行遍历,让右边界尽可能小

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        if not intervals:
            return 0
        #将所有区间按右端点进行排序
        intervals.sort(key=lambda x: x[1])
        n = len(intervals)
        right = intervals[0][1]
        ans = 1   #ans记录非交叉区间的个数
        for i in range(1, n):
            if intervals[i][0] >= right:
                ans += 1
                right = intervals[i][1]
        
        return n - ans    

方法二:按左边界排序,从右到左进行遍历,让左边界尽可能大

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        #按左边界进行排序,从右到左遍历,让左边界尽可能大
        intervals.sort(key=lambda x:x[0])
        #print(intervals)
        n=len(intervals)
        res=1
        maxv=intervals[-1][0]
        for i in range(n-2,-1,-1):
            if intervals[i][1]<=maxv:
                res+=1
                maxv=intervals[i][0]
        return n-res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值