区间合并算法
问题:对输入的区间如[1,2][2,6][3,5][7,9]进行合并,输出[1,6][7,9]
思路1:如果数据较小,可开辟一大数组,如上述数据,开辟一个大小为100的布尔型数组对在区间内的赋值true。扫描输出为true的数字。
思路2:定义left和right,
(1)开始left和right分别为第一个区间的左右,
(2)从第二个区间开始遍历,如果第二个区间左值大于第一个区间右值则存储第一个,第二个的左右为新的left和right。
(3)否则比较第二个的右值和第一个的右值,如果第二个的右值大于第一个右值
则更新第二个的右值为新的right。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<pair<int, int>> QJ;
bool comp(pair<int,int>& p1,pair<int,int>& p2) //按第一个元素大小升序排列
{
return p1.first < p2.first;
}
QJ cover(QJ& q, int n)
{
QJ res;
int left = q[0].first;
int right = q[0].second;
for (int i = 1; i < n; i++)
{
if (q[i].first > right) //下一个区间的开始大于上一个的结束
{
res.push_back(make_pair(left, right)); //上一个直接存储
left = q[i].first; //更新left\right
right = q[i].second;
}
else if (q[i].second > right) //下一个的开始小于等于上一个结束而且下一个结束大于上一个结束
{
right = q[i].second; //更新right
}
}
res.push_back(make_pair(left, right));//最后一次由于没有了比较所以没存入
return res;
}
void main()
{
QJ q, res;
int N, start, end;
cout << "输入区间个数" << endl;
cin >> N;
cout << "输入区间" << endl;
for (int i = 0; i < N; i++)
{
cin >> start >> end;
q.push_back(make_pair(start, end));
}
sort(q.begin(), q.end(), comp);//按第一个元素大小升序排列
cout << "区间显示" << endl;
for (int i = 0; i < N; i++)
{
cout << "[" << q[i].first << "," << q[i].second << "]" << " ";
}
cout << endl;
res = cover(q, N);
cout << "合并后区间显示" << endl;
for (int i = 0; i < res.size(); i++)
{
cout << "[" << res[i].first << "," << res[i].second << "]" << " ";
}
system("pause");
}