这个题的意思是:给定一组"区间",将所有能够合并的区间合并,返回最终的区间的集合。
说实话拿到这个题的时候多么希望这些区间是有序的(就是所有区间按照起始大小排好序了),为此我强行将它当作有序的,还写了代码进行提交,然而结果是题目给出了 "[[2,3],[4,5],[6,7],[8,9],[1,10]]" 这样的测试用例。好吧,说明这些区间是无序的,这下难度增加了很多,说实话解题的思路我一时真的没想到,想的快要放弃了,曾想看看别的代码,但是还是忍住了。经过今早一番的思索,终于找到了解题思路,所以要分享出来:
我的思路是:取出集合(tmp)的第一个区间[s,e],然后从后面的区间中找能够融合的区间,若可以融合则去掉这个被融合的区间(此时[s,e]可能会扩大),若是不能融合的话先将它放到一个额外空间中(额外空间_swap),最后将将额外空间的元素代替原始空间中的元素(tmp=_swap,这样就去掉了那些被融合的元素),然后再依次遍历tmp,直到最后tmp中只剩一个元素了,此时问题就解决了。
其中每遍历完一趟后,我们需要作个决策:就是当前区间能不能直接当作最终问题的解集(ret)的一个元素(若是的话就将它加入的问题最终的解的集合(ret)中),那么怎样判断他是独立的呢(意思它不能再跟任何区间融合了),我是这样解决的:
每趟遍历开始的时候我设置一个 bool 值(bool flag=false),在遍历的过程中,若区间被融合了则把它设置为true(说明区间[s,e]被扩大了,被扩大的区间很有可能与之前被过滤的区间再次融合,所以我们不能直接将它加入到问题的最终的解集(ret)中),举个例子说明一下吧:
若区间集合为:"[[2,3],[4,9],[3,6],[11,15]] "
1.我们首先选择的区间是[2,3]
2.往后遍历的过程中,区间[4,9]会被过滤掉(被添加到_swap中去了,因为它无法和[2,3]融合),但是在后面遇到区间 [3,6] 的时候,区间[2,3]被融合成了[2,6],这个时候[2,6]是不能被添加到问题的最终得解集(ret)中的,因为之前错过了区间[4,9],所以应该将它继续添加到_swap中(这个时候flag是被置为ture的,因为区间[2,3]发生了融合),这样下次[4,9]与[2,6]就能够融合了。
3.若是遍历完一趟后,flag仍然为flas,则说明该区间不会融合了,所以应该将它直接加入到问题最终的解集(ret)中
4.遍历到tmp只剩一个元素的时候,直接将这个元素加入到ret中即可.
我相信我说明白了这个问题了,下面给上代码吧:
/**
* 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:
vector merge(vector& intervals)
{
vector ret;
vector tmp = intervals; //这样主要是为了不改变intervals的值
vector _swap; //保留区
while (tmp.size() > 1)
{
bool flag = false;
_swap.clear();
int pos = 0;
int next = pos + 1;
int tail = tmp.size();
int s = tmp[pos].start;
int e = tmp[pos].end;
while (next < tail)
{
if (tmp[next].end >= s && tmp[next].start <= e)
{ //该条件满足了,说明[s,e]可能得到了延伸,tmp[next]元素被融合了,应该去掉了
flag = true;
e = max(e, tmp[next].end);
s = min(s, tmp[next].start);
}
else
{ //不能融合的先留下
_swap.push_back(tmp[next]);
}
++next;
}
//将留下的继续融合
tmp.clear();
tmp = _swap;
if (!flag)
{ //此时说明了[s,e]区间中不会再有重叠的部分了,也就是说它是独立的
ret.push_back(Interval(s, e));
}
else
{ // 说明[s,e]区间延伸了,无法预测他是否还可以与其他部分融合,所以它很可能再和其他的融合
tmp.push_back(Interval(s, e));
}
}
if (tmp.size() == 1)
{
ret.push_back(tmp[0]);
}
return ret;
}
};