博客
关于我
leetcode 986 、56 ——区间问题(数组区间的并集和交集)
阅读量:526 次
发布时间:2019-03-08

本文共 2137 字,大约阅读时间需要 7 分钟。

前缀和技巧

区间问题

区间问题主要包含两种操作:交集和并集。交集要求找到两个区间列表中同时存在的重叠部分,而并集则要求合并所有重叠的区间。

区间交集

为了解决区间交集问题,可以使用双指针法。假设输入两个已经排序的区间列表A和B,分别用两个指针i和j指向当前的区间。在每一步中,比较A[i]和B[j]的交集情况。

  • 交集条件

    • 两个区间存在交集,当且仅当A[i].start ≤ B[j].end且B[j].start ≤ A[i].end。
  • 移动指针

    • 如果满足交集条件,记录交集区间的起点和终点,注意取较大的起点和较小的终点。
    • 如果不满足交集条件,比较A[i].end和B[j].end的大小。若A[i].end较小,则将i指针向前移动(因为此时A[i]已经在B[j]之前,没有交集);否则,将j指针向前移动(因为此时B[j]已经在A[i]之前,没有交集)。
  • 代码示例

    以下是C++实现:

    #include 
    using namespace std;vector
    > intervalIntersection(vector
    > A, vector
    > B) { vector
    > res; int i = 0, j = 0; int lenA = A.size(), lenB = B.size(); while (i < lenA && j < lenB) { int a1 = A[i][0], a2 = A[i][1]; int b1 = B[j][0], b2 = B[j][1]; if (a1 <= b1 && a2 >= b1 && a1 <= b2 && a2 >= b2) { // 计算交集区间 int start = max(a1, b1); int end = min(a2, b2); res.push_back({start, end}); if (a2 < b2) { i++; } else { j++; } } else { // 不存在交集的情况 if (a2 < b1) { i++; } else { j++; } } } return res;}

    区间合并

    对于区间的并集,我们可以先按起点排序,然后用双指针法合并相邻重叠的区间。

  • 排序

    • 将区间列表按起点从小到大排序。
  • 合并步骤

    • 初始化结果列表,首先将第一个区间添加进去。
    • 对于剩下的区间,检查它是否与结果列表最后一个区间重叠。
      • 如果重叠,则更新结果列表最后一个区间的终点为当前区间的终点。
      • 如果不重叠,则将当前区间添加到结果列表的最后。
  • 代码示例

    以下是C++实现:

    #include 
    #include
    using namespace std;vector
    > merge(intervals) { vector
    > res; sort(intervals.begin(), intervals.end(), [](const vector
    & a, const vector
    & b) { return a[0] < b[0]; }); if (intervals.empty() || intervals.size() == 1) { return intervals; } res.push_back(intervals[0]); for (size_t i = 1; i < intervals.size(); ++i) { const vector
    & current = intervals[i]; const vector
    & last = res.back(); if (current[0] <= last[1]) { // 重叠的情况,更新终点 if (current[1] > last[1]) { last[1] = current[1]; } } else { // 不重叠,添加新区间 res.push_back(current); } } return res;}

    总结

    区间问题中,寻找交集和合并都是常见操作。通过双指针法,我们可以高效地解决这些问题。交集处理需仔细比较起点和终点的关系,而合并则依赖于排序后的区间列表。理解这些技巧有助于你在面对类似问题时灵活应对。

    转载地址:http://spuiz.baihongyu.com/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(一) :直接拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(三):基于特征匹配拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(二) :基于模板匹配拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV常用图像拼接方法(四):基于Stitcher类拼接
    查看>>
    OpenCV与AI深度学习 | OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测(建议收藏!)
    查看>>
    OpenCV与AI深度学习 | PaddleOCR 2.9 发布, 正式开源文本图像智能分析利器
    查看>>
    OpenCV与AI深度学习 | SAM2(Segment Anything Model 2)新一代分割一切大模型介绍与使用(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | T-Rex Label !超震撼 AI 自动标注工具,开箱即用、检测一切
    查看>>
    OpenCV与AI深度学习 | YOLO11介绍及五大任务推理演示(目标检测,图像分割,图像分类,姿态检测,带方向目标检测)
    查看>>
    OpenCV与AI深度学习 | YOLOv10在PyTorch和OpenVINO中推理对比
    查看>>
    OpenCV与AI深度学习 | YOLOv11来了:将重新定义AI的可能性
    查看>>
    OpenCV与AI深度学习 | YOLOv8自定义数据集训练实现火焰和烟雾检测(代码+数据集!)
    查看>>
    OpenCV与AI深度学习 | YOLOv8重磅升级,新增旋转目标检测,又该学习了!
    查看>>
    OpenCV与AI深度学习 | 一文带你读懂YOLOv1~YOLOv11(建议收藏!)
    查看>>
    OpenCV与AI深度学习 | 五分钟快速搭建一个实时人脸口罩检测系统(OpenCV+PaddleHub 含源码)
    查看>>
    OpenCV与AI深度学习 | 什么是 COCO 数据集?
    查看>>
    OpenCV与AI深度学习 | 低对比度缺陷检测应用实例--LCD屏幕脏污检测
    查看>>
    OpenCV与AI深度学习 | 使用 MoveNet Lightning 和 OpenCV 实现实时姿势检测
    查看>>
    OpenCV与AI深度学习 | 使用 OpenCV 创建自定义图像滤镜
    查看>>
    OpenCV与AI深度学习 | 使用 SAM 和 Grounding DINO 分割卫星图像
    查看>>