题目
Given a collection of intervals, merge all overlapping intervals.
Example 1:
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Example 2:
Input: [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considerred overlapping.
算法思路
输入:一堆区间的集合
输出:集合中交叉的区间合并后,按小到大顺序排列
考虑到区间是分布在一条数轴上的,先按照区间下限把无序的区间先排好序,此时合并区间时只需要考虑相邻区间的关系即可,减少了很多关于是否需要合并的判断。
遍历排序后的数组时,相邻两个区间的关系可能的情况有两种:
- 相交,即前者上限大于等于后者下限,此时两者合并成新区间,新区间下限取前者下限,新区间上限取两者上限中较大的那个,用新区间作为下一次比较的前者。
- 无相交,将前者区间存到新的数组中。
C++代码
使用C++STL库中的vector时需要注意使用reserve函数预先设置好数组的大小,否则测试数据较大时,会多次超出分配数据段的容量,从而多次重新分配新的数据段,这个重分配十分耗时,会导致RuntimeError.
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
static bool cmp(Interval i,Interval j) {
return (i.start < j.start);
}
vector<Interval> merge(vector<Interval>& intervals) {
vector<Interval> res;
res.reserve(intervals.size());
if (intervals.size() == 0) {
return res;
}
std::sort(intervals.begin(), intervals.end(), cmp);
Interval now = intervals[0];
for(int i = 1; i < intervals.size(); i++) {
if (now.end >= intervals[i].start) {
if (now.end < intervals[i].end) {
now.end = intervals[i].end;
}
}
else {
res.push_back(now);
now = intervals[i];
}
}
res.push_back(now);
return res;
}
};