引言
这个区间合并顾名思义就是把区间给合并起来,所以说也就只有这一种题型,然后这个一般面试或者笔试可能会考,所以说总结一下还是好的,那就开始吧。
一、题目描述
给定 n 个区间 [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1 ≤ n ≤ 100000, −109 ≤ li ≤ ri ≤ 109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3
二、解题思路
首先我们的这个区间必须是以左端点由大到小排好序的,然后在进行处理。
其实这个区间合并无非就两种情况,如下图所示,
第一种情况:下一个区间的
左端点
左端点
左端点 比上一个区间的
右端点
右端点
右端点 小,那就将
r
=
m
a
x
(
r
,
n
e
w
r
)
r = max(r, new_r)
r=max(r,newr) ,找到这两个区间
右端点
右端点
右端点 最大的一个更新区间
第二种情况:下一个区间的
左端点
左端点
左端点 比上一个区间的
右端点
右端点
右端点 大,那么上一个区间就可以加入到结果集中了,然后更新目前的区间的
左右端点
左右端点
左右端点
三、代码实现
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int,int> PII;
#define x first
#define y second
int n;
void merge(vector<PII>& segs)
{
vector<PII> res;
sort(segs.begin(), segs.end());
int l = -2e9, r = -2e9;
for(int i = 0; i < segs.size(); ++i)
{
if(segs[i].x > r)
{
if(r != -2e9) res.push_back({l,r});
l = segs[i].x, r = segs[i].y;
}
else
{
r = max(r, segs[i].y);
}
}
if(r != -2e9) res.push_back({l,r}); //最后一个区间因为没人比了,所以要加进来,当然如果初始区间为空就不行了
segs = res; //最后将结果集拷贝给segs,通过引用传出去
}
int main()
{
scanf("%d", &n);
vector<PII> segs;
for(int i = 0; i < n; ++i)
{
int l, r;
scanf("%d%d", &l, &r);
segs.push_back({l,r});
}
merge(segs);
printf("%d\n", segs.size());
return 0;
}
四、测试
可以看到测试样例是通过了的,然后总的测试用例也是全部通过