算法基础 -- 区间合并

区间合并

问题:

给定 n 个区间 [ l , r ],要求合并所有有交集的区间。(如果在端点处相交,也算有交集)
输出合并完成后的区间个数。

核心思想:

首先按每个区间的左端点进行排序,然后再依次处理剩下三种可能存在交集的情况

  1. 区间1的右端点在区间2左端点的左边(无交集)
  2. 区间1的右端点在区间2左端点的右边 (有交集)
  3. 区间1包含区间2 (有交集)

注意: 代码中 -2e9 因为 int 的最小值为−2147483647 ~ 2147483647,所以取−2e9 ~ 2e9比较省事,可以代表int的最小值。

#include
#include
#include

using namespace std;

typedef pair<int , int> PII;

void merge(vector<PII> &segs)
{
    vector<PII> res;
    sort(segs.begin(),segs.end());  //按左端点排序
    
    int st = -2e9 , ed = -2e9;  //初始时选中的区间
    for(auto seg : segs)    //最后一个区间时不会有下一个区间进行比较了,因此循环后要处理。
    {
        if(ed < seg.first)  //表示:当前区间与下一个区间没有交集
        {
            if(st != -2e9) res.push_back({st,ed});
            st = seg.first, ed = seg.second;    //选中下一个区间进行处理
        }
        else ed = max(ed, seg.second);  //否则就将区间合并
    }
    //对最后一个区间进行判断
    if(st != -2e9) res.push_back({st,ed});  //if是为了防止传入为空时将{st=-2e9, ed=-2e9}插入数组
    segs = res;
}

int main()
{
    int n, l, r;
    vector<PII> segs;
    cin >> n;
    while (n --)
    {
        cin >> l >> r;
        segs.push_back({l,r});
    }
    
    merge(segs);
    
    cout << segs.size() << endl;
    
    return 0;
}

你可能感兴趣的:(数据结构算法基础,算法,贪心算法,数据结构)