class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
          if (intervals.size() == 0){
            return {};
        }
        vector<vector<int>>merged;
        sort(intervals.begin(),intervals.end());
        for(int i = 0;i<intervals.size();i++){
            int l=intervals[i][0],r=intervals[i][1];
            if(merged.size()==0 || merged.back()[1]<l){
                merged.push_back({l,r});
            }
            else{
                merged.back()[1] = max(merged.back()[1],r);
            }
        }
        return merged;
    }
};

这道题你可以把它压缩成一个非常好记的思路:

先排序,再逐个比较;能合并就扩右边界,不能合并就加入答案。

具体来说,先用:

sort(intervals.begin(), intervals.end());

把所有区间按照左端点从小到大排序。排序之后,我们只需要拿“当前区间”和 merged 里最后一个已经合并好的区间比较。

如果:

merged.back()[1] < l

说明前一个区间的右端点比当前区间左端点还小,二者没有重叠:

[1,3]   [5,7]

所以直接:

merged.push_back({l,r});

如果不满足:

merged.back()[1] < l

那就说明:

merged.back()[1] >= l

两个区间重叠,例如:

[1,4]
   [3,7]

此时左端点不用动,只需要把右端点扩大:

merged.back()[1] = max(merged.back()[1], r);

所以整道题可以记成:

排序
 ↓
遍历每个区间 [l,r]
 ↓
结果为空?
或者
最后区间右端点 < 当前左端点?
 ↓
是:直接加入
否:更新最后区间右端点为 max

这道题容易忘的函数/语法

sort(intervals.begin(), intervals.end());

含义:对整个 vector 排序。

对于:

vector<vector<int>>

默认会先比较:

intervals[i][0]

也就是区间左端点;左端点相同,再比较右端点。


merged.back()

表示:

取 merged 的最后一个元素。

因为:

merged

是:

vector<vector<int>>

所以:

merged.back()

本身就是最后一个:

vector<int>

例如:

merged = {{1,6},{8,10}};

那么:

merged.back()

就是:

{8,10}

于是:

merged.back()[0]

是:

8

左端点。

merged.back()[1]

是:

10

右端点。

这道题重点记:

merged.back()[1]

= 最后一个已合并区间的右端点。


merged.push_back({l,r});

表示:

把新区间 [l,r] 加到结果最后面。

比如:

l = 8;
r = 10;

执行:

merged.push_back({l,r});

就是加入:

{8,10}

你之前问过 emplace_back,这道题直接坚持:

push_back({l,r});

就可以,不需要想复杂。


max(a,b)

返回二者中的较大值。

这里:

merged.back()[1] = max(merged.back()[1], r);

意思就是:

两个区间发生重叠时,把右边界扩展到更远的位置。

例如:

[1,4]
[2,7]

那么:

max(4,7) = 7

最终:

[1,7]

还有一个容易混淆的地方:

merged.size() == 0

表示结果数组为空。

也可以写:

merged.empty()

所以这句:

if(merged.size()==0 || merged.back()[1]<l)

以后你可以写成更容易读的:

if(merged.empty() || merged.back()[1] < l)

含义完全一样。

最后,你刷题时只需要背住这 3 行核心逻辑:

sort(intervals.begin(), intervals.end());

if(merged.empty() || merged.back()[1] < l)
    merged.push_back({l,r});
else
    merged.back()[1] = max(merged.back()[1], r);

口诀就是:

“左端点排序,看最后一个;不重叠就加,重叠就扩右边界。”

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐