scau 18962 区间合并

scau 18962 区间合并,第1张

Description
字节跳动面试题。

给出N个区间,请合并所有重叠的区间。比如[10,30],[20,60],可以合并成[10,60]。
下面4个区间
[[10,30],[80,100],[150,180],[20,60],]
可以合并成3个区间
[[10,60],[80,100],[150,180]]
按区间左端点的次序输出合并后的所有区间。
  输入格式
第一行一个整数N(1<=N<=100000)。
第二行到第N+1行,每行2个整数,代表区间的左右端点。
输出格式
按区间左端点的次序输出合并后的所有区间,每行输出一个区间。
输入样例
4
10 30
80 100
150 180
20 60
输出样例
10 60
80 100
150 180

这道题的解法不难,关键在于代码怎么写。

相信大家应该不难发现,只有当一个区间的右端点大于另一个区间的左端点,且该区间的左端点大于另一个区间的右端点,这两个区间才能合并,对吧。

我们可以定义一个结构体来表示区间。a[].l代表左端点,a[].r代表右端点。

struct node
{
    int l,r;
};

struct node a[100005];

题目要求按区间左端点的次序输出合并后的所有区间,那么我们先对所有区间进行一个排序。

bool cmp(node a,node b)//升序排序
{
    if(a.l!=b.l)
        return a.l

打断一下,我在这里补充一下sort函数的用法。

      sort有两种形式,一个有两个参数,一个有三个参数。大家可能比较熟悉两个参数的sort,sort的前两个参数是起始地址和终止地址,如sort(a+1,a+n+1)是对a[1]…a[n]进行排序,不过这样是默认升序的哦。如果想降序怎么办呢?这时候就需要引进第三个参数,它是一个比较函数,如下

bool cmp(int a,int b) 
{ 
    return a > b;
}

它的意思是,当a>b时,为true,不交换;a

不仅仅可以对数组进行排序,也可以对结构体进行排序。写法和上面一样。在上面的bool cmp(node a,node b)函数中,对结构体数组a按左端点l进行排序,如果左端点相同,则按右端点r进行排序,当然,这个函数直接写成return a.l

回归正题。

我们知道,要求一个合并区间,就要比较当前区间右端点和该区间后面区间左端点的大小。我们可以设置两个指针L和R,初始化——L指向当前区间的左端点,R指向当前区间的右端点。通过当前区间右端点和该区间后面区间左端点的比较,我们不断更新R的指向当当前区间右端点大于该区间后面某一区间左端点时,我们的R指向这某一区间的右端点。当R所指向的右端点小于后面某一区间的左端点时,我们就找到了一个合并的区间,并输出这个合并区间。输出完后,记得更新L和R的值哦,使它们分别指向下一个区间的左右端点。

全部代码如下。

#include 
#include 
#include 

using namespace std;

struct node
{
    int l,r;
};

struct node a[100005];
int n;

bool cmp(node a,node b)//升序排序
{
    if(a.l!=b.l)
        return a.l> n;
    for(int i=1;i<=n;i++)
        cin >> a[i].l >> a[i].r;
    sort(a+1,a+n+1,cmp);//升序排序
    a[n+1].l=2e9;//设置一个很大的数,方便最后一组区间进行比较
    int L=a[1].l,R=a[1].r;//初始化L和R
    for(int i=1;i<=n+1;i++)
    {
        if(a[i].l<=R)
            R=max(R,a[i].r);
        else
        {
            cout << L << ' '<

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/921633.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-16
下一篇2022-05-16

发表评论

登录后才能评论

评论列表(0条)