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]
.
Subscribe to see which companies asked this question
這道題和編程之美上2.19 區間重合判斷很像。都可以採用線段樹的思想實現。
將給定的區間集合按照區間左端點從小到大排列。
合併的時候注意區間右端點要進行比較,取較大者。
代碼如下(已AC 2016-03-28):
struct Interval {
int start;
int end;
Interval() : start(0), end(0) {}
Interval(int s, int e) : start(s), end(e) {}
};
// 按照區間左端點從小到大排列
bool cmp(const Interval& a, const Interval& b)
{
return a.start < b.start;
}
vector<Interval> merge(vector<Interval>& v) {
if (v.size() <= 0) return vector<Interval>();
// 先按照start從小到大排序
sort(v.begin(), v.end(), cmp);
vector<Interval>::iterator it = v.begin();
int st = (*it).start, ed = (*it).end;
vector<Interval> res;
for (; it != v.end(); ++it)
{
// 除去最後一個區間
if ((it + 1) != v.end())
{
// 區間不能合併
if ((it + 1)->start > ed)
{
res.push_back(Interval(st, ed));
st = (it + 1)->start;
}
// 要比較區間的結束 有可能出現[1 5] [2 4] 這樣區間結束是較大者
ed = ((it + 1)->end > ed) ? (it + 1)->end : ed;
}// end if
// 最後一個區間單獨考慮
else
{
if (it->start > ed)
{
res.push_back(Interval(st, ed));
res.push_back(*it);
}//end if
else
{
ed = ((it)->end > ed) ? (it)->end : ed;
res.push_back(Interval(st, ed));
}//end else
}//end else
}//end for
return res;
}