Given a collection of intervals, merge all overlapping intervals.
For example,
Given [1,3],[2,6],[8,10],[15,18]
,
return [1,6],[8,10],[15,18]
.
题目自定义了一个Interval结构体,包含了两个成员变量start和end。
思路:
构造一个新的vector命名为res,用来存储并返回。
先将vector中的元素从小到大排序,因为是自定义的struct,所以我们没法直接使用自带的sort函数,可以参考C++ Primer中文第五版P344中10.3节编写新的sort函数。这里将struct中的start变量从小到大比较。
排序后,循环遍历vector保存的区间,如果后一个区间的start不大于res中最后一个区间的end,则取两个闭区间中end较大的保存,否则将区间存入新的vector。
/**
* 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 mycompare(const Interval &a,const Interval &b){
return a.start<b.start;
}
vector<Interval> merge(vector<Interval> &intervals) {
vector<Interval> res;
if(intervals.empty()) return res;
sort(intervals.begin(),intervals.end(),mycompare);
res.push_back(intervals[0]);
for(int i=1;i<intervals.size();++i){
if(res.back().end>=intervals[i].start)
res.back().end=max(res.back().end,intervals[i].end);
else res.push_back(intervals[i]);
}
return res;
}
};
2017-11-29更新
先将序列排序是因为题意中并没有说明序列是以怎么样的顺序给出,不要被题目中的例子所误导。
将序列按左端点大小从小到大排列后,采用以下的算法:
1.新建一个集合来保存返回结果,遍历排序后的序列,如果是第一个区间则直接加入新集合。
2.后面的区间要和前面的区间比较,具体为如果后面的区间的左端点大于前一区间的右端点则直接添加;否则用此时遍历到的区间右端点和
新集合中最后一个区间的右端点中的较大值来更新新集合中
最后一个区间的
右端点。
该算法的正确性可用反证法证明。
时间复杂度:O(NlgN);空间复杂度:O(1)。
Java实现
/**
* Definition for an interval.
* public class Interval {
* int start;
* int end;
* Interval() { start = 0; end = 0; }
* Interval(int s, int e) { start = s; end = e; }
* }
*/
class Solution {
private class IntervalComparator implements Comparator<Interval>
{
public int compare(Interval a,Interval b)
{
if(a.start<b.start)
return -1;
else if(a.start==b.start)
return 0;
else
return 1;
}
}
public List<Interval> merge(List<Interval> intervals) {
if(intervals.isEmpty()||intervals.size()==1)
return intervals;
LinkedList<Interval> newIntervals=new LinkedList<Interval>();
Collections.sort(intervals,new IntervalComparator());
for(Interval interval:intervals)
{
if(newIntervals.isEmpty()||newIntervals.getLast().end<interval.start)
newIntervals.add(interval);
else
{
newIntervals.getLast().end=Math.max(newIntervals.getLast().end,interval.end);
}
}
return newIntervals;
}
}