C++算法之区间合并

本文介绍区间合并相关知识点

目录

文章目录

前言

区间合并

概述

做法

n个区间合并

校门外的树

总结


前言

本文介绍区间合并这一基础算法,介绍常规的做法以及模板


区间合并

概述

通常区间合并是给定数个区间,想要将有交集的区间合并成一个区间

如下要求,就是通常遇见区间合并问题的简化

给定 n 个区间 [l,r],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。

做法

区间合并算法通常用于将具有重叠部分的区间进行合并,得到不重叠的区间集合。

  1. 区间表示:通常使用一个二元组 (start, end) 表示一个区间,其中 start 表示起始位置,end 表示结束位置。

  2. 区间排序:首先需要对给定的区间按照起始位置进行排序,可以使用快速排序、归并排序等算法。

  3. 遍历合并:遍历排序后的区间集合,从第一个区间开始,逐个检查当前区间与下一个区间是否有重叠部分。

  4. 合并操作:如果当前区间与下一个区间存在重叠,则更新当前区间的结束位置为两个区间中较大的结束位置;否则将当前区间添加到结果集,并更新当前区间为下一个未合并的区间。

  5. 循环迭代:重复步骤 4 直到遍历完所有的区间。

  6. 输出结果:最终得到的不重叠的合并后的区间即为最终结果。

    下面我将使用一俩个例子具体解析一下区间合并问。

n个区间合并

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

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

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

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

输入格式
第一行包含整数n。

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

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

数据范围
1≤n≤1000001≤n≤100000
−109≤l≤r≤109
样例
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3

按照做法中的顺序,我们首先要将二元组 (start, end) 表示一个区间存储下来

在这里我们通常使用pair<int,int>来存储一个二元组,使用vector来存储所有二元组

接下来我们需要进行vector存储元素排序,直接使用sort函数进行排序即可,默认情况下,比较pair中第一个元素,即我们需要的按左端点排序

然后开始遍历所有区间,进行区间合并操作,合并操作分为三种情况讨论,如下:

  1. 两个区间无法合并,即前区间的右端点<后区间的左端点,这种情况下,俩个区间没有交集,就无法合并,我们可以将前区间存入另一个vector中作为合并好的区间,然后开始维护合并后区间
  2. 俩个区间可以合并,即后区间的左端点<前区间的右端点<后区间的右端点,这种情况下区间变为,{前区间左端点,后区间右端点},然后继续和下一个区间比较
  3. 第三种情况就是前区间的右端点>后区间的右端点,不需要处理,因为前区间以及包容后区间

对于2/3的情况其实可以直接让后区间=max(前区间的右端点,后区间的右端点) 处理即可

综上本题先按左端点排序,再维护一个区间,与后面一个个区间进行三种情况的比较,存储到数组里去。

本题代码如下:

#include<iostream> 
#include<vector>
#include<algorithm>
using namespace std;const int N = 1e5 +10;
typedef pair<int,int> PII;
int n; 
vector<PII> a;
vector<PII> ans ; 
int main() 
{cin>>n; for(int i = 0;i<n;i++) {int x,y; cin>>x>>y;  a.push_back({x,y});}sort(a.begin(),a.end()); int st = -1e9-1,ed = -1e9-1;    //st,ed要比最小值小,否则可能会出现错误for(int i = 0;i<n;i++){ if(ed < a[i].first)                    //情况1:两个区间无法合并{if(st != -1e9 - 1)                   //首先判断当前是否以及有区间~{ans.push_back({st, ed});        //区间1放进ans数组}st = a[i].first;ed = a[i].second; //维护区间2} else ed = max(ed,a[i].second);              //区间合并} if(st != -1e9 - 1)  ans.push_back({st, ed}); //考虑循环结束时的st,ed变量,此时的st,ed变量不需要继续维护,只需要放进res数组即可。//因为这是最后的一个序列,所以不可能继续进行合并。cout<< ans.size()<<endl;return 0;
}

校门外的树

题目描述
某校大门外长度为 L 的马路上有一排树,每两棵相邻的树之间的间隔都是 1 米。

我们可以把马路看成一个数轴,马路的一端在数轴 0 的位置,另一端在 L 的位置;数轴上的每个整数点,即 0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。

这些区域用它们在数轴上的起始点和终止点表示。

已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。

现在要把这些区域中的树(包括区域端点处的两棵树)移走。

你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式

输入文件的第一行有两个整数 L 和 M,L 代表马路的长度,M 代表区域的数目,L 和 M 之间用一个空格隔开。

接下来的 M 行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出格式

输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

样例

输入样例:
500 3
150 300
100 200
470 471
输出样例:
298

本题有俩种方法,一个是暴力枚举,另一个是区间合并

方法一:暴力模拟法

开辟一个长度为 L + 1 的 bool 数组,每个元素代表树的状态: true: 有树, false:没有树。

遍历每条地铁,把地铁区间内的树砍掉,即对应数组元素置为 false。

统计数组中还有多少个 true ,就是还是剩多少棵树。

 方法二:区间合并
1. 将要砍掉树的区间合并在一起,合并后的区间没有重合部分。例如:[1~3]和[3~5] 合并成 [1~5]。
2. 数的总数 - 合并后所有区间覆盖的点数 = 剩余树的数量。

区间合并:
1. 将区间按左端点升序排序。
2. 从第一个区间开始,如果该区间的右端点大于后面相邻区间的左端点,当前区间右端点更新为:该区间右端点和相邻区间右端点最大值。直到不能继续合并,然后开始后面区间合并。

代码如下:

#include <iostream>
#include <algorithm>
using namespace std;const int N = 110;int n, m;
pair<int, int> undg[N];//存储地铁区间
int main()
{cin >> n >> m;int res = n + 1;for(int i = 0; i < m; i++ ) cin >> undg[i].first >> undg[i].second;sort(undg,undg + m);//按照左端点排序int st = undg[0].first, ed = undg[0].second;//起始区间for(int i = 1; i < m; i++){if(ed >= undg[i].first) ed = max(ed, undg[i].second);//的右端点大于后面相邻区间的左端点,合并在一起else// 否则重新开始合并{res -= ed - st + 1;//减去当前区间的树的数量st = undg[i].first;//新维护区间的左端点ed = undg[i].second;//新维护区间的右端点}}res -= ed - st + 1;//减去最后一个地铁区间的树木cout << res<< endl;
}

总结

介绍了区间合并算法的解决方法,同时给了俩道例题实现了区间合并算法

推荐学习博客 https://xxetb.xetslk.com/s/4GgGz6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/10590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识付费程序源码_30秒轻松搭建知识付费小程序_免费试用,知识付费工具有哪些?哪个比较好用?

继2016年知识付费大火之后&#xff0c;衍生出很多关于知识付费的平台或工具。除了得到APP、荔枝微课、千聊等需要用户作为“客”家申请入驻的流量型平台&#xff0c;还有一些其他的知识付费工具&#xff0c;那么有哪些呢? 知识付费工具&#xff0c;推荐使用系统。 自2016年知识…

蓝桥杯第246题——矩阵计数

题目描述 一个 NM 的方格矩阵&#xff0c;每一个方格中包含一个字符 O 或者字符 X。 要求矩阵中不存在连续一行 3 个 X 或者连续一列 3 个 X。 问这样的矩阵一共有多少种&#xff1f; 输入描述 输入一行包含两个整数 N,M (1≤N,M≤5)。 输出描述 输出一个整数代表答案。…

SpringBoot内置插件的使用(jackson和lombok)

文章目录 引言I lombok(自动为属性生成构造器)II jacksonsee also引言 idea2021.2.2 已经捆绑安装jackson和lombok插件 I lombok(自动为属性生成构造器) Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。 https://p…

Spring Cloud Gateway详解

文章目录 Gateway搭建路由&#xff08;route&#xff09;断言&#xff08;Predicate &#xff09;自定义断言 过滤器&#xff08;filter&#xff09;自定义全局过滤器 引言 在传统的单体项目中&#xff0c;前端和后端的交互相对简单&#xff0c;只需通过一个调用地址即可实现。…

【C语言题解】用函数来模拟实现strlen()、strcpy()、strcmp()、strcat()

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ 学习了函数后&#xff0c;老师让我们用函数来实现上面这四个字符串函数。 我们首先来了解一下这四个字符串函数&#xff1a; 1.strlen函数 用于获取字符串长度&#xff08;不包括末尾…

每日OJ题_贪心算法四②_力扣435. 无重叠区间

目录 力扣435. 无重叠区间 解析代码 力扣435. 无重叠区间 435. 无重叠区间 难度 中等 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,2]…

机器学习-有监督学习

有监督学习是机器学习的一种主要范式&#xff0c;其基本思想是从有标签的训练数据中学习输入和输出之间的关系&#xff0c;然后利用学习到的模型对新的输入进行预测或分类。 有监督学习的过程如下&#xff1a; 1. 准备数据&#xff1a;首先&#xff0c;需要准备一组有标签的训练…

WPF EventSetter 写法

感觉这玩意之前一直没用过&#xff0c;可能在容器里用到的比较多吧&#xff0c;记录一下。 第一种代码法&#xff1a; Style itemContainerStyle new Style(typeof(ListBoxItem));itemContainerStyle.Setters.Add(new Setter(ListBoxItem.AllowDropProperty, true));itemCont…

IDEA安装使用Git

IDEA安装使用Git 1 Git下载与安装 2 在IDEA中使用Git 2.1 IDEA中配置Git 在IDEA中使用Git&#xff0c;本质上还是使用本地安装的Git软件&#xff0c;所以需要在IDEA中配置Git。 2.2 在IDEA中使用Git 2.2.1 获取Git仓库 在IDEA中使用Git获取仓库有两种方式: 本地初始化仓库从…

CentOS7 安装 Kamailio

https://www.kamailio.org/wiki/packages/rpms 官方文档说 yum -y install yum-utils yum-config-manager --add-repo https://rpm.kamailio.org/centos/kamailio.repo 但目前这样其实行不通 需要这样做&#xff1a; yum install --disablerepokamailio --enablerepokamai…

软件测试面试题学习

参考视频&#xff1a;软件测试面试——接口测试用例该怎么设计_哔哩哔哩_bilibili 1. 接口测试用例该怎么设计&#xff1f; a.功能测试用例的时候针对的是单接口&#xff0c;提交的一个各种正向或逆向的一些测试数据 b.业务测试用例&#xff0c;

Python异步编程之道:asyncio库的探索与应用

Python异步编程之道&#xff1a;asyncio库的探索与应用 一、引言 在Python编程中&#xff0c;异步编程是提高程序性能、处理高并发场景的重要技术。传统的同步编程模型在处理I/O密集型任务时&#xff0c;如网络请求、文件读写等&#xff0c;会导致CPU的空闲等待&#xff0c;从…

数据库出现死锁的解决方法参考

死锁引起的原因一般是多个用户并发访问数据库导致的问题&#xff0c;或是因为某个进程挂死以后资源未释放导致的。通过onstat –p可查看deadlks项大于0即表示历史总计死锁次数。对于被锁的表进行操作的时候会出现-143 ISAM error: deadlock detected的错误。当其他会话访问此表…

从JSON数据到Pandas DataFrame:如何解析出所需字段

目录 一、引言 二、JSON数据的基本结构 三、使用Pandas从JSON数据中读取数据 四、从DataFrame中解析出所需字段 解析对象字段 解析嵌套对象字段 解析数组字段 五、案例与代码示例 六、总结 一、引言 在数据分析和处理的日常工作中&#xff0c;我们经常需要从各种…

UBoat:一款功能强大的HTTP Botnet学习与研究工具

关于UBoat UBoat是一款功能强大的HTTP Botnet概念验证工具&#xff0c;该工具支持复刻一个现实场景中完整功能的Botnet测试环境&#xff0c;广大研究人员可以利用UBoat深入学习和研究Botnet的工作机制&#xff0c;以此来提升安全检测和保护策略。 功能介绍 1、基于C开发&…

luceda ipkiss教程 70:合并GDS版图

通过代码拼版&#xff1a; 所有代码如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3class Design1(i3.GDSCell):def _default_filename(self):return "Ring_Test.gds"def _default_name(self):return "Design1"class Des…

VTK官方例子

VTK官方例子 vtkMutableDirectedGraph #!/usr/bin/env python# noinspection PyUnresolvedReferences import vtkmodules.vtkInteractionStyle # noinspection PyUnresolvedReferences import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.vtkCommonColor import vtkName…

EasyExcel自定义数据格式化

自定格式常量类 public class ExcelFormatConstants {public static final String DATE_FORMAT "yyyy-MM-dd";public static final String NUMBER_FORMAT_DEFAULT "#,##0.00";public static final String NUMBER_FORMAT_FOUR_DECIMAL "#,##0.0000…

Apache Flume事务

Apache Flume 中的事务处理是指 Flume Agent 在处理事件流时的一种机制&#xff0c;用于确保数据的可靠传输和处理。 1. 事务概述&#xff1a; Flume 中的事务是指一组事件的传输和处理&#xff0c;这些事件在传输过程中要么全部成功完成&#xff0c;要么全部失败&#xff0…

Jsp+Servlet实现图片上传和点击放大预览功能(提供Gitee源码)

前言&#xff1a;在最近老项目的开发中&#xff0c;需要做一个图片上传和点击放大的功能&#xff0c;在Vue和SpringBoot框架都有现成封装好的组件和工具类&#xff0c;对于一些上世纪的项目就没这么方便了&#xff0c;所以需要自己用原生的代码去编写&#xff0c;这里分享一下我…