做笔试题遇到一道区间合并的题目,给定若干区间[1,2] [2,3] [4,5]合并有覆盖的区间,即为[1,3] [4,5]。经过在网上搜索类似题目,得到两种解题思路。类似题目是LeetCode上的56题目
思路1.如果区间的端点范围很小,比如在范围[0,9999]。可以开一个10000大小的bool数组,然后输入区间覆盖的范围都复制true。则最后遍历数组,连续的true数据即为一个区间。这种方法适用于区间范围小,区间的平均跨度不是很大。
思路2. 首先,按区间的左端点排序,然后比较left和right值。比如区间[1,3] [2,6] [8,10]
第一步:[1,3],赋值left=1 ,right = 3
第二步:区间[2,6]的2与right值比较,2<3,表示这两个区间连接在一起,判断6与right值的大小,决定新的right值
第三步:区间[8,10]的8比新的right6大,即出现新的区间,存储上一个left和right。赋值新的left和right
分析一下时间复杂度,排序的时候是O(NlogN),然后线性扫一遍是O(N),所以总的时间复杂度是O(NlogN),跟区间的跨度没关系,跟区间端点的覆盖范围也没一毛钱关系!
只跟区间的个数有关系,而且还是很可以接受的一个复杂度(毕竟log N跟常数的区别不是很大)。
代码:
#include
#include
#include
using namespace std;
typedef vector > RangeList;
RangeList cover(const RangeList& intervals) {
int left = intervals[0].first, right = intervals[0].second;
RangeList result;
for (int i = 1; i < intervals.size(); ++i) {
if (intervals[i].first > right) { // 前面自成一个区间,那么就此分开
result.push_back(make_pair(left, right));
left = intervals[i].first;
right = intervals[i].second;
} else if (intervals[i].second > right) {
right = intervals[i].second;
}
}
result.push_back(make_pair(left, right));
return result;
}
void display(const RangeList& intervals) {
for (int i = 0; i < intervals.size(); ++i)
cout << intervals[i].first << ' ' << intervals[i].second << endl;
cout << endl;
}
int main() {
RangeList intervals;
int n, start, end;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> start >> end;
intervals.push_back(make_pair(start, end));
}
sort(intervals.begin(), intervals.end()); //对输入的区间排序
RangeList result = cover(intervals);
display(result);
return 0;
}
代码中用到一个定义方式是vector
使用pair对,在vector中插入成对的数据
声明vector:
vector
往vector中插入数据,需要用到make_pair:
vec.push_back(make_pair
vec.push_back(make_pair(20,30));
定义迭代器:
vector
for(iter=vec.begin();iter!=vec.end();iter++);
数据读取:
第一个数据:(*iter).first
第二个数据:(*iter).second
对vector
#include "stdafx.h"
#include
#include
#include
using namespace std;
//根据first的值升序排序
bool cmp1(paira,pairb)
{
return a.first < b.first; //a.first > b.first降序
}
//根据second的值升序排序
bool cmp2(paira, pairb)
{
return a.second < b.second;
}
int main()
{
vector>vec;
vec.push_back({ 1,2 });
vec.push_back({ 4,2 });
vec.push_back({ 3,3 });
vec.push_back({ 2,1 });
sort(vec.begin(), vec.end(), cmp1);
cout << "根据first的值升序排序:" << endl;
for (auto it = vec.begin();it != vec.end();it++)
{
cout << "(" << it->first << "," << it->second << ")" << endl;
}
sort(vec.begin(), vec.end(), cmp2);
cout << "根据second的值升序排序:" << endl;
for (auto it = vec.begin();it != vec.end();it++)
{
cout << "(" << it->first << "," << it->second << ")" << endl;
}
}