算法学习系列(十二):区间合并

引言

这个区间合并顾名思义就是把区间给合并起来,所以说也就只有这一种题型,然后这个一般面试或者笔试可能会考,所以说总结一下还是好的,那就开始吧。

一、题目描述

给定 n 个区间 [li,ri],要求合并所有有交集的区间。

注意如果在端点处相交,也算有交集。

输出合并完成后的区间个数。

例如:[1,3][2,6] 可以合并为一个区间 [1,6]。

输入格式
第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。

输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。

数据范围
1 ≤ n ≤ 100000,109 ≤ li ≤ ri ≤ 109

输入样例:
5
1 2
2 4
5 6
7 8
7 9

输出样例:
3

二、解题思路

首先我们的这个区间必须是以左端点由大到小排好序的,然后在进行处理。
其实这个区间合并无非就两种情况,如下图所示,
第一种情况:下一个区间的 左端点 左端点 左端点 比上一个区间的 右端点 右端点 右端点 小,那就将 r = m a x ( r , n e w r ) r = max(r, new_r) r=max(r,newr) ,找到这两个区间 右端点 右端点 右端点 最大的一个更新区间
第二种情况:下一个区间的 左端点 左端点 左端点 比上一个区间的 右端点 右端点 右端点 大,那么上一个区间就可以加入到结果集中了,然后更新目前的区间的 左右端点 左右端点 左右端点

在这里插入图片描述

三、代码实现

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef pair<int,int> PII;
#define x first
#define y second

int n;

void merge(vector<PII>& segs)
{
    vector<PII> res;
    sort(segs.begin(), segs.end());
    
    int l = -2e9, r = -2e9;
    for(int i = 0; i < segs.size(); ++i)
    {
        if(segs[i].x > r)
        {
            if(r != -2e9) res.push_back({l,r});
            l = segs[i].x, r = segs[i].y;
        }
        else
        {
            r = max(r, segs[i].y);
        }
    }
    
    if(r != -2e9) res.push_back({l,r});  //最后一个区间因为没人比了,所以要加进来,当然如果初始区间为空就不行了
    
    segs = res;  //最后将结果集拷贝给segs,通过引用传出去
}

int main()
{
    scanf("%d", &n);
    vector<PII> segs;
    for(int i = 0; i < n; ++i)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        segs.push_back({l,r});
    }
    
    merge(segs);
    
    printf("%d\n", segs.size());
    
    return 0;
}

四、测试

可以看到测试样例是通过了的,然后总的测试用例也是全部通过
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lijiachang030718

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值