笔试题69. LeetCode OJ (56)

来源:互联网 发布:蝎子网络第一季百度云 编辑:程序博客网 时间:2024/05/16 03:59

    这个题的意思是:给定一组"区间",将所有能够合并的区间合并,返回最终的区间的集合。

说实话拿到这个题的时候多么希望这些区间是有序的(就是所有区间按照起始大小排好序了),为此我强行将它当作有序的,还写了代码进行提交,然而结果是题目给出了 "[[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<Interval> merge(vector<Interval>& intervals)     {  vector<Interval> ret;vector<Interval> tmp = intervals; //这样主要是为了不改变intervals的值vector<Interval> _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;}};

程序的结果如下:


0 0