区间合并
注意:此算法并不是双指针算法,因为只需要将题目给出的所有区间遍历一次即可。
区间合并
题目描述
给定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
题解
两个按照左端点从小到大排好序的待合并区间总共会有以下三种情况:
-
第一个区间:st ed ↓ ↓ |________| 第二个区间: |___| ↑ ↑ l r
-
第一个区间:st ed ↓ ↓ |________| 第二个区间: |________| ↑ ↑ l r
前两种情况我们可以将合并为一种情况:当第二个区间的左端点
l
在第一个区间内部时(l>=st && l<=ed
),更新右端点ed
即可。 -
第一个区间:st ed ↓ ↓ |________| 第二个区间: |______| ↑ ↑ l r
第三种情况,第二个区间的左端点大于第一个区间的右端点时(
l>ed
),st
和ed
都分别更新为第二个区间的左右端点。
完成上述过程还有一个重要的前提条件,就是要先将所有的区间按照左端点从小到大排好序才可以根据以上思路进行。
代码1
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 7;
pair<int, int> a[N];
int main(void)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i].first >> a[i].second;
sort(a + 1, a + n + 1);
int st, ed, ans = 1;
for (int i = 1; i <= n; ++i)
{
if (i == 1)
{
st = a[i].first;
ed = a[i].second;
continue;
}
if (a[i].first >= st && a[i].first <= ed)
ed = max(ed, a[i].second);
else if (a[i].first > ed)
{
st = a[i].first;
ed = a[i].second;
ans++;
}
}
cout << ans;
return 0;
}
TIPS
sort
函数对pair
默认为对first
升序,当first
相同时对second
升序。
代码2
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PR;
const int N = 1e5 + 7;
vector<PR> a;
void merge(vector<PR> &x)
{
vector<PR> ans;
sort(a.begin(), a.end());
int st = -2e9, ed = -2e9;
for (auto i : a)
{
if (ed < i.first)
{
if (st != -2e9) ans.push_back({ st, ed });
st = i.first, ed = i.second;
}
else ed = max(ed, i.second);
}
if (st != -2e9) ans.push_back({ st, ed });
a = ans;
}
int main(void)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
int l, r;
cin >> l >> r;
a.push_back({ l, r });
}
merge(a);
cout << a.size();
return 0;
}
代码3
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int E = -2e9;
vector<pair<int, int>> a;
void merge(vector<pair<int, int>>& x)
{
vector<pair<int, int>> ans;
sort(x.begin(), x.end());
int st = E, ed = E;
for (auto i : x)
if (st == E && ed == E)
st = i.first, ed = i.second;
else if (i.first > ed)
{
st = i.first, ed = i.second;
ans.push_back({ st, ed });
}
else ed = max(ed, i.second);
ans.push_back({ st, ed });
x = ans;
}
int main(void)
{
int n;
cin >> n;
while (n--)
{
int l, r;
cin >> l >> r;
a.push_back({ l, r });
}
merge(a);
cout << a.size();
return 0;
}
代码4
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int E = -2e9;
vector<pair<int, int>> a;
vector<pair<int, int>> merge(vector<pair<int, int>>& x)
{
vector<pair<int, int>> ans;
sort(x.begin(), x.end());
int st = E, ed = E;
for (auto i : x)
if (st == E && ed == E)
{
st = i.first, ed = i.second;
ans.push_back({ st, ed });
}
else if (i.first > ed)
{
st = i.first, ed = i.second;
ans.push_back({ st, ed });
}
else ed = max(ed, i.second);
return ans;
}
int main(void)
{
int n;
cin >> n;
while (n--)
{
int l, r;
cin >> l >> r;
a.push_back({ l, r });
}
cout << merge(a).size();
return 0;
}