这道题目之前在代码随想录里面刷过,还有点印象,直接用贪心算法做了。用贪心算法需要先将整个二维数组进行排序,排序规则就是向量的左侧端点小的排在前面,然后我们定义好排序规则后利用sort
函数对输入数组进行排序,然后遍历整个向量,在初始时,定义第一个向量的左右端点分别为left
和right
,然后每遍历到一个左端点小于left
的区间,就将该区间加入到前一个区间,此时我们需要维护right
的值,如果当前遍历到的向量的右端点值>right
,则将right
更新为当前向量的右端点值,否则保持原来的值。这里还有一个要注意的点,当遍历结束后,还有最后一个区间没有加入到结果中,所以在循环结束后我们需要手动将[left, rifht]
添加到result
中。下面是贪心的代码。
class Solution {
public:
static bool My_Compare(const vector<int>& a, const vector<int>& b){
//这里,输入的两个向量分别对应两个区间
//我们根据区间的左端点进行升序排列
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> result;
//对输入的二维向量中的向量进行升序排列
sort(intervals.begin(), intervals.end(), My_Compare);
int left = intervals[0][0];
int right = intervals[0][1];
for(vector<int>& v : intervals){
if(v[0] <= right){
right = max(v[1], right);
}
else{
result.push_back({left, right});
left = v[0];
right = v[1];
}
}
result.push_back({left, right});
return result;
}
};
看了下灵神的题解,思路也是贪心,但是他的代码简洁很多,这里也把他的代码贴出来学习一下。
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
ranges::sort(intervals); // 按照左端点从小到大排序
vector<vector<int>> ans;
for (auto& p : intervals) {
if (!ans.empty() && p[0] <= ans.back()[1]) { // 可以合并
ans.back()[1] = max(ans.back()[1], p[1]); // 更新右端点最大值
} else { // 不相交,无法合并
ans.emplace_back(p); // 新的合并区间
}
}
return ans;
}
};