算法基础集训(第17天,共106天)------>轻松学会【区间合并】,附上图文以及详细思路解析和代码解析,搞不懂来找我

6a8c0954aea6451b9249cbc3921a9c09.gif

目录

一:概念定义 

 

二:题目描述 

 

三:思路解析 

 

四:万年无误代码模板 

 

 


 

一:概念定义 

合并所有有交集的区间。例如【2,4】和【3,7】,取其并集得到【2,7】为最终结果

画个图帮助理解

a978da710d864700a08a374d92e09cf9.png



二:题目描述 

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

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

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

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

输入格式

第一行包含整数 n。

接下来 n 行,每行包含两个整数 l 和 r。

输出格式

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

数据范围

 

1 ≤ n ≤ 100000,
−10^9 ≤ l ≤ r ≤ 10^9

输入样例

5

1 2

2 4

5 6

7 8

7 9

输出样例 

3


三:思路解析 

首先,题目会输入很多的区间,区间的左右端点杂乱无章,如果要合并只能用暴力的方式,但是暴力显然过不了所有数据。因此,容易联想到根据左端点从小到大排序,排序完成之后,正在维护的区间和该区间右侧的区间只有3种情况,如下图:080ceb9fadd94a47aa9ad65cd42ecfd4.png

第一种情况:正在维护的区间的左右端点都不用改变,因为求并集之后还是原区间

第二种情况:正在维护的区间的右端点小于右侧区间的右端点且两个区间有交集,因此要更新右端点

第三种情况:正在维护的区间和右侧区间没有交集,所以更新答案res++,且将右侧区间作为下一轮需要维护的区间

用到的结构:由于输入依然是成对出现,因此还是考虑用pair结构存储数据,另外,对pair排序时,会默认先对第一个关键字排序。


四:万年无误代码模板 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std ;
typedef pair<int,int> PII ;
vector<PII> nums,res ;
int main()
{
    int st=-2e9,ed=-2e9 ;                           //ed代表区间结尾,st代表区间开头
    int n ;
    scanf("%d",&n) ; 
    
    while(n--)
    {
        int l,r ; 
        scanf("%d%d",&l,&r) ;
        nums.push_back({l,r}) ;
    }
    
    sort(nums.begin(),nums.end()) ;//按左端点排序
    
    for(auto num:nums)    //遍历所有输入               
    {
        if(ed<num.first)                            //对应思路解析的情况3:两个区间无法合并
        {
            if(ed!=-2e9) res.push_back({st,ed}) ;   //只要不是初始状态的无限区间,就可以放入答案数组
            st=num.first,ed=num.second ;            //更新区间
        }
        //对应思路解析的情况2:两个区间可以合并,且区间1不包含区间2,区间2不包含区间1
        else if(ed<num.second)  
            ed=num.second ;                         //更细右端点,合并两个区间
    }  
    //(实际上也有思路解析的情况1:区间1包含区间2,此时不需要任何操作,可以省略)

    //注:排过序之后,右侧区间不可能包含被维护的区间

    res.push_back({st,ed});

    //考虑循环结束时的st,ed变量,此时的st,ed变量不需要继续维护,它的后面没有区间了,所以无法进去第一个if内部放入res中,
    //因此只需要放进res数组即可。
    
    printf("%d",res.size()) ; 
    return 0 ;
}

创作不易,建议点赞+收藏+关注,以免找不到宝贝文章了。

基础集训结束后将开展拔高系列

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码kobe

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

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

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

打赏作者

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

抵扣说明:

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

余额充值