C++ 区间合并 算法(详解) + 例题

1、定义

  • 把所有,有交集的区间合并

  • 图解:

      

2、实现

  • 步骤如下:
    • 1、首先按照每个区间左端点排序

    • 2、扫描 所有区间,进行区间合并

    • 上述第二条,可以理解为:拿出一个区间去跟它后面的所有的区间去进行合并(因为我们先拿出左端点去排序,所以不用害怕后面的区间会小于什么的)。

  • 图解:

      

· 代码模板: 

//将所有存在交集的区间进行合并
void merge(vector<PII> &segs)
{
    vector<PII> res;
    sort(segs.begin(),segs.end());
    int st = -2e9,ed = -2e9;
    for(auto seg : segs)
    {
        if(ed < seg.first)
        {
            if(st!=-2e9) res.push_back({st,ed});
            st = seg.first,ed = seg.second;
        }
        else ed = max(ed,seg.second);
    }
    if(st!=-2e9) res.push_back({st,ed});
    segs = res;
}

3、例题:803. 区间合并 - AcWing题库

  • 给定 n个区间 [li ri],要求合并所有有交集的区间。

    注意如果在端点处相交,也算有交集。

    输出合并完成后的区间个数。

    例如: [1,3] 和 [2,6] 可以合并为一个区间 [1,6]。

    输入格式

    第一行包含整数 n。

    接下来 n 行,每行包含两个整数 l 和 r。

    输出格式

    共一行,包含一个整数,表示合并区间完成后的区间个数。

    数据范围

    1≤n≤100000      −10 ^ 9 ≤ li ≤ ri ≤ 10 ^ 9

  • 输入样例:
    5
    1 2
    2 4
    5 6
    7 8
    7 9
    输出样例:
    3

    图解:

        

AC代码(这里给出两种写法): 

#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<utility>


using namespace std;
typedef pair<int,int> PII;
const int N = 100010;
vector<PII> segs;
int n;

//区间合并
void merge(vector<PII> &segs)
{
    vector<PII> res;//用来存储
    //按区间的左端点来进行排序,然后再按照第二个排序(pair很像)
    sort(segs.begin(),segs.end());
    将st(start)和ed(end)初始化为负无穷,确保端点一定在左面
    int st = -2e9, ed = -2e9;
    for(auto seg : segs)
    {
        //如果比较区间的左端点不在当前区间中
        if(ed < seg.first)
        {
            //判断一下是否更新 新的当前区间(以防第一次更新)
            if(st!=-2e9) res.push_back({st,ed});
            st = seg.first,ed = seg.second;//更新区间,变成当前区间
        }
        //如果比较区间的左端点在区间中更新一下最大的右端点
        else ed = max(ed,seg.second); 
    }
    //看一下,最后一个元素是否被合并
    if(st!=-2e9) res.push_back({st,ed});
    
    segs = res;
}

int main()
{
    cin >> n;
    //存入坐标
    for(int i=0;i<n;i++)
    {
        int l,r;
        cin >> l >> r;
        segs.push_back({l,r});
    }
    //区间合并
    merge(segs);
    
    cout << segs.size() << endl;
    return 0;
}
第二种: 
#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> PII;
vector<PII> segs;
int n,res;

int main()
{
    cin >> n;
    for(int i=0;i<n;i++)
    {
        int l,r;
        cin >> l >> r;
        segs.push_back({l,r});
    }
    
    sort(segs.begin(),segs.end());
    int ed = segs[0].second;
    for(int i=1;i<n;i++)
    {
        if(ed < segs[i].first)
        {
            res++;
            ed = segs[i].second;
        }
        else ed = max(ed,segs[i].second);
    }
    
    cout << res + 1 << endl;
    return 0;
}

相关推荐

  1. C++算法区间合并

    2024-02-20 18:22:02       36 阅读
  2. 算法详解】力扣56.合并区间

    2024-02-20 18:22:02       58 阅读
  3. 算法| ss 合并区间

    2024-02-20 18:22:02       32 阅读
  4. 算法刷题笔记 区间合并C++实现)

    2024-02-20 18:22:02       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-20 18:22:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-20 18:22:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-20 18:22:02       82 阅读
  4. Python语言-面向对象

    2024-02-20 18:22:02       91 阅读

热门阅读

  1. 【Qt笔记】QSS中常见的伪状态

    2024-02-20 18:22:02       46 阅读
  2. css中, grid-auto-rows: 怎样简写在grid:中

    2024-02-20 18:22:02       45 阅读
  3. Flink容错机制

    2024-02-20 18:22:02       50 阅读
  4. 分享15个基本且常用Pandas代码(建议收藏)

    2024-02-20 18:22:02       43 阅读
  5. 零基础学c++(第二节)

    2024-02-20 18:22:02       49 阅读
  6. 时序数据库TDengine窗口函数

    2024-02-20 18:22:02       45 阅读