区间合并

概念

区间合并就是将若干个有交集的区间合成一个大区间

思路

将每个区间按照左右端点成对存储,并排序,以区间左端点从小到大排序,如果下一个区间的左端点大于当前区间的右端点说明这两个区间不能合并;
同时因为sort后,如果下一个区间的开头大于当前区间的末尾,那么当前区间就可以直接存入结果当中,后面不会再有区间可以与其合并;

例题

链接:https://www.acwing.com/problem/content/805/
给定 n 个区间 [l,r],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。

题解

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii ;
vector<pii> nums,res ;//num用来存储当前区间,res用来存储已经无法合并的区间,本题其实不需要res记录结果区间,只要一个int cnt计数就可以
int main()
{
    //ed代表区间结尾,st代表区间开头
    int st=-2e9,ed=-2e9 ;
    int n ;
    cin >> n;
    while(n--)
    {
        int l,r ; 
        cin >> l >> r
        nums.push_back({l,r}) ;
    }
    //按first,即区间的开头排序
    sort(nums.begin(),nums.end()) ;
    //遍历,相当于for (int num=0; num<nums.length; num++)
    for(auto num:nums)                   
    {
        //情况1:下一区间的开头大于当前区间的末尾,说明不能合并
        if(ed<num.first)
        {
            // //因为sort后,如果小区间的开头大于大区间的末尾,只要不是初始化的区间,那么大区间就可以直接放进res数组
            if(ed!=-2e9) 
            res.push_back({st,ed}) ; 
            //维护,现在num用来维护当前区间
            st=num.first,ed=num.second ;
        }
        //情况2:如果大区间的末尾,大于小区间的开头,说明两个区间可以合并,且大区间不包含小区间,小区间不包含大区间
        else if(ed<num.second)  
            //区间合并
            ed=num.second ;
    }  
    //考虑循环结束时的st,ed变量,此时的st,ed变量不需要继续维护,只需要放进res数组即可。
    //因为这是最后的一个序列,所以不可能继续进行合并。
    res.push_back({st,ed});

    cout << res.size() << endl;
    return 0 ;
}
posted @ 2022-07-21 09:08  Zilliax  阅读(346)  评论(0)    收藏  举报