区间合并
介绍
假定给出n个区间,将有交集的区间合并,最后求出合并后的区间个数。
核心思想:
区间合并步骤:
-
按区间左端点排序
-
扫描每个维护区间(假设维护区间是蓝色线段),将可能有交集的区间合并,这里会出现一下三种情况
-
第一种: 更新完之后区间不变
-
第二种:更新完后区间发生变化
-
第三种:维护区间已经合并结束,即最终区间。接下来将红色区间替换为下一个维护区间。
-
模板代码:
typedef pair<int, int> PII;
const int MIN = 0xc0c0c0c0; // 无穷小
vector<PII> segs; // 存储读入的区间
// 输入待合并区间segs,将其修改为排序过后的合并区间segs
void merge(vector<PII> &segs)
{
vector<PII> res; // 存储最终的合并区间
sort(segs.begin(), segs.end()); // 按左端点排序
int left = MINX, right = left;
for( auto seg : segs )
{
if ( seg.first > right )
{
// 将合并区间添入res
if(first != MIN) res.push_back({left, right});
// 替换维护区间
left = seg.first;
right = seg.second;
}
else right = max(right, seg.second); // 更新维护区间
}
res.push_back({left, right}) // 将最后一个合并区间添入res
segs = res;
}
例题
思路:
按上述模板进行区间合并
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 10e5 + 10;
const int MIN = 0xc0c0c0c0;
typedef pair<int, int> PII;
vector<PII> segs;
void merge(vector<PII> &segs)
{
vector<PII> res; // 最终的合并区间
int left = MIN, right = left; // left和right定义为无穷小
sort(segs.begin(), segs.end());// 排序,这里pair会依据第一个排序,第一个相同再依据第二个排序
for(auto seg : segs )
{
if( seg.first > right )// 替换维护区间
{
if(left != MIN) res.push_back({left, right});
left = seg.first;
right = seg.second;
}
else right = max(right, seg.second); // 更新维护区间右端点
}
res.push_back({left, right}); // 将最后一个区间添加进res
segs = res;
}
int main()
{
int n; cin >> n;
for(int i=0; i<n; i++)
{
int l, r;
cin >> l >> r;
segs.push_back({l, r});
}
merge(segs);
// for(auto seg : segs)
// {
// cout << seg.first << ' ' << seg.second << endl;
// }
cout << segs.size();
}