Leetcode 56
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
链接:https://leetcode-cn.com/problems/merge-intervals
区间合并类型的问题一般都要对左端点或者右端点进行排序,然后再进行区间的合并就方便了,因为左端点或者右端点已经有序了。
对这道题来说前后紧挨着的区间的相对位置关系只有3种:
1. st1 ed1 两区间相互包含
st2 ed2
2. st1 ed1 两区间不完全包含但有交叉
st2 ed2
3. st1 ed1 两区间完全没有交集
st2 ed2
4. 不会出现这种情况 st1 ed1 因为之前对区间的左端点排过序了,后面区间的左端点不
st2 ed2 可能超过前面区间的左端点最多相同。
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if (intervals.size() == 0) return intervals; // 这次的空区间是[]没有[[]]
vector<vector<int>> res;
vector <int> pro;
sort(intervals.begin(),intervals.end()); // 区间合并问题:按照左端点排序区间
int st = intervals[0][0];
int ed = intervals[0][1];
for (int i = 1 ;i < intervals.size();){
if (ed >= intervals[i][0]){
ed = max(ed,intervals[i][1]);
++i;
}else{ // 如果此时的ed严格小于下一个区间的st,那么当前的[st,ed]之后也没有区间再和它相交了,因为前面对左端点进行了从小到大的排序,那么当前的[st,ed]就可以压入结果容器res中了。
pro.push_back(st);
pro.push_back(ed);
res.push_back(pro);
pro.clear(); // 容器pro 清空
st = intervals[i][0]; // 更新st和ed的值
ed = intervals[i][1];
i ++;
}
}
pro.push_back(st); // 把最后一次合并得到的区间压入结果容器res中。
pro.push_back(ed);
res.push_back(pro);
return res;
}
};
Acwing 803
? https://www.acwing.com/problem/content/805/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int count = 0 ,n;
vector <pair<int,int>> v; // 容器里存放了pair数据结构,思路和leetcode上的题思路是一样的
cin>>n;
while(n--){
int st,ed;
scanf("%d%d",&st,&ed);
v.push_back({st,ed});
}
sort(v.begin(),v.end());
int st = v[0].first;
int ed = v[0].second;
for (int i = 1 ; i < v.size() ;++i){
int stt= v[i].first;
int edd = v[i].second;
if (stt <= ed) ed = max(edd,ed);
else{
st = v[i].first;
ed = v[i].second;
count ++;
}
}
if (ed != v[0].second) count = count + 1;
cout<<count<<endl;
return 0;
}