当前位置: 首页 > article >正文

【435. 无重叠区间 中等】

题目:

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。

注意 只在一点上接触的区间是 不重叠的。例如 [1, 2] 和 [2, 3] 是不重叠的。

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

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

示例 3:
输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

提示:

  • 1 <= intervals.length <= 105
  • intervals[i].length == 2
  • -5 * 104 <= starti < endi <= 5 * 104

思路:

这道题有两个思路:

  1. 记录重叠区间个数,重叠区间个数就是最小移除次数
  2. 记录非交叉区间个数,最小移除次数 = 区间总数 - 非交叉区间个数

看到这道题目都冥冥之中感觉要排序,但是究竟是按照右边界排序,还是按照左边界排序呢?

其实都可以。主要就是为了让区间尽可能的重叠。

这里按照右边界排序。

针对思路2,记录非交叉区间的个数还是有技巧的,如图:
在这里插入图片描述
区间,1,2,3,4,5,6都按照右边界排好序。

当确定区间 1 和 区间2 重叠后,如何确定是否与 区间3 也重贴呢?

就是取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的。

接下来就是找大于区间1结束位置的区间,是从区间4开始。那有同学问了为什么不从区间5开始?别忘了已经是按照右边界排序的了。

区间4结束之后,再找到区间6,所以一共记录非交叉区间的个数是三个。

总共区间个数为6,减去非交叉区间的个数3。移除区间的最小数量就是3。


代码:

  1. 思路一
class Solution {
public:
    //  按照右边界排序
    static bool cmp(vector<int>& a, vector<int>& b){
        return a[1] < b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int result = 0;  //  记录重叠区间的个数

        for(int i = 1; i < intervals.size(); i++){
            if(intervals[i][0] < intervals[i - 1][1]){ //  如果重叠
                intervals[i][1] = min(intervals[i - 1][1], intervals[i][1]);    //  更新区间分割点
                result++;    //  重叠区间个数加一
            }
        }
        return result;    //  重叠区间个数就是最小移除次数
    }
}; 
  1. 思路二
class Solution {
public:
    //  按照右边界排序
    static bool cmp(vector<int>& a, vector<int>& b){
        return a[1] < b[1];
    }
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        if(intervals.size() == 0) return 0;
        sort(intervals.begin(), intervals.end(), cmp);
        int count = 1;  //  记录非交叉区间的个数
        int end = intervals[0][1];  //  记录区间分割点

        for(int i = 1; i < intervals.size(); i++){
            if(end <= intervals[i][0]){ //  如果不交叉
                end = intervals[i][1];  //  更新区间分割点
                count++;    //  非交叉区间个数加一
            }
        }
        return intervals.size() - count;    //  最小移除次数 = 区间个数 - 非交叉区间的个数
    }
}; 

总结:

时间复杂度:O(nlog n) ,有一个快排
空间复杂度:O(n),有一个快排,最差情况(倒序)时,需要n次递归调用。因此确实需要O(n)的栈空间


参考:

代码随想录


http://www.kler.cn/a/532577.html

相关文章:

  • Web3.js详解
  • 如何不更新application.yml而更新spring的配置
  • Debezium Oracle Connector SCN处理优化指南
  • 玉米苗和杂草识别分割数据集labelme格式1997张3类别
  • 【hot100】刷题记录(12)-回文链表
  • Apache Hudi数据湖技术应用在网络打车系统中的系统架构设计、软硬件配置、软件技术栈、具体实现流程和关键代码
  • K8s 分布式存储后端(K8s Distributed Storage Backend)
  • 基础IOIO
  • PHP 调用 DeepSeek API 完整指南
  • 【字节青训营-7】:初探 Kitex 字节微服务框架(使用ETCD进行服务注册与发现)
  • 机器学习day8
  • sql中奇数、偶数、正则
  • 【L2JMobius】ZGC requires Windows version 1803 or later
  • 宝塔面板端口转发其它端口至MySQL的3306
  • 关于大模型 AGI 应知应会_生在AI发展的时代
  • 51单片机入门_05_LED闪烁(常用的延时方法:软件延时、定时器延时;while循环;unsigned char 可以表示的数字是0~255)
  • 统计满足条件的4位数(信息学奥赛一本通-1077)
  • 【通俗易懂说模型】线性回归(附深度学习、机器学习发展史)
  • 高斯过程处理大型数据集时返回值为 0 的问题
  • Spring Cloud工程搭建
  • 中继器与集线器
  • 用deepseek制作我的第一个长视频---使用AI解决尝试新领域没有经验拖延的问题!
  • 在Mac mini M4上部署DeepSeek R1本地大模型
  • Linux下使用C++设计线程池
  • 路由表转发表考研知识点
  • 强化学习驱动的自适应模型选择与融合用于监督学习