题目如下:
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].
分析如下:
一堆乱数无法merge, 很自然地想到要对intervals做排序,因为interval有start 和end两个值,为了方便选择start作为key进行排序。排序之后,考虑区间的merge情况。想象区间b从区间a的左侧逐渐水平方向右移,于是区间a , b出现这几种相交关系。
第一种: 包含型, 如 [1,9] [2,3], merge后成为[1,9], 新interval的end是左区间[1,9]的end。
第二种: 相交型1, 如 [1,6] [2,8], merge后成为[1,8],新interval的end是右区间[2,8]的end。
第三种: 无交集,如 [1,3] [5,9], 不需要merge,。
我的代码:
//88ms class Solution { public: // void print_interval_vector(vector<Interval> interval_vec) { // for (int i = 0; i < interval_vec.size(); ++i) { // std::cout<<"["<<interval_vec[i].start<<", "<<interval_vec[i].end<<"]"<<", "; // } // std::cout<<std::endl; // } // vector<Interval> make_input(int input[][2], int len) { // vector<Interval> res; // for (int i = 0; i < len; ++i) { // Interval a; // a.start = input[i][0]; // a.end = input[i][1]; // res.push_back(a); // std::cout<<"a.start = "<<a.start<<", a.end="<<a.end<<std::endl; // } // return res; // } static bool my_interval(const Interval & a, const Interval &b) { //神奇的是,如果把比较函数写在class 外面就runtime error了。 return (a.start < b.start); } vector<Interval> merge(vector<Interval> &intervals) { vector<Interval> after_merge; if (intervals.size() == 0) return after_merge; std::sort(intervals.begin(), intervals.end(), Solution::my_interval); after_merge.push_back(intervals[0]); for (int i = 1; i < intervals.size(); ++i) { if (intervals[i].start <= after_merge.back().end) { //注意end是需要两个区间中取值较大的那个。 after_merge.back().end = intervals[i].end > after_merge.back().end? intervals[i].end:after_merge.back().end; } else { after_merge.push_back(intervals[i]); } } return after_merge; } };
如果使用仿函数就会发生runtime error,我不知道为什么会这样。
后来弄清楚原因了,也算一个坑。仿函数当然是可以用的。关键是只能用<,不能用<=。 std::sort()是用的<,所以自己去写排序的仿函数的时候,要么用<要么用>,而不能用<=或者>=。所以这样写也是对的。
//88ms struct MyInterval{ bool operator()(const Interval & interval1, const Interval & interval2) { //return (interval1.start <= interval2.start); //std::sort()的定义决定了这里不能加等号,否则会runtime error return (interval1.start < interval2.start); } }my_interval; class Solution { public: vector<Interval> merge(vector<Interval> &intervals) { vector<Interval> after_merge; if (intervals.size() == 0) return after_merge; std::sort(intervals.begin(), intervals.end(), my_interval); after_merge.push_back(intervals[0]); for (int i = 1; i < intervals.size(); ++i) { Interval & merge_to = after_merge.back(); Interval & merge_from = intervals[i]; if (intervals[i].start <= after_merge.back().end) { after_merge.back().end = intervals[i].end > after_merge.back().end? intervals[i].end:after_merge.back().end; } else { after_merge.push_back(intervals[i]); } } return after_merge; } };