题目描述
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
解题思路
从例子可以看出,两个区间若能合并,则第一个区间的右端点一定不小于第二个区间的左端点。所以先把区间集合按照左端点从小到大进行排序,接着从第一个区间开始遍历,对每个区间执行如下操作:
- 首先保存该区间的左端点start和右端点end
- 从该区间的下一个区间开始,依次比较此区间的左端点与上一个区间的右端点,若满足合并条件则记录新合并区间的右端点。注意右端点取当前区间与之前区间右端点的较大值
- 若当前区间不再满足合并条件或者遍历到了集合末尾,就构建新合并区间,其中左端点为初始区间的左端点,右端点为当前所有合并区间右端点的最大值,然后将其加入到结果集合中,接着合并下一个区间
代码
1 /** 2 * Definition for an interval. 3 * struct Interval { 4 * int start; 5 * int end; 6 * Interval() : start(0), end(0) {} 7 * Interval(int s, int e) : start(s), end(e) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<Interval> merge(vector<Interval>& intervals) { 13 sort(intervals.begin(), intervals.end(), cmp); 14 if(intervals.size() == 1) 15 return intervals; 16 vector<Interval> res; 17 int i = 0; 18 while(i < intervals.size()){ 19 int start = intervals[i].start, end = intervals[i].end; 20 int j = i+1; 21 while(j < intervals.size() && intervals[j].start <= end){ 22 if(end < intervals[j].end) 23 end = intervals[j].end; 24 j++; 25 } 26 struct Interval merge = {start, end}; 27 res.push_back(merge); 28 i = j; 29 } 30 return res; 31 } 32 static bool cmp(Interval a, Interval b){ 33 return a.start < b.start; 34 } 35 };