基础算法篇(4)(蓝桥杯常考点)—数据结构(进阶)

前言

这期将会讲到基础算法篇里面的数据结构(进阶),主要包括单调栈,单调队列,并查集,扩展域并查集,带权并查集,字符串哈希,Trie树。

数据结构(进阶)正文

单调栈

里面存储的单增或者单减的栈

应用:

1.寻找当前元素左侧,离它最近,并且比它大的元素在哪

2.寻找当前元素左侧,离它最近,并且比它小的元素在哪

3.寻找当前元素右侧,离它最近,并且比它大的元素在哪

4.寻找当前元素右侧,离它最近,并且比它小的元素在哪

寻找当前元素左侧,离它最近,并且比它大的元素在哪
int a[N]里面存数(已存好)
ret里面存的答案
stack<int>st;//维护一个单调递减的栈,里面存的是下标
for(int i = 1;i<=n;i++)
{
//栈里面小于等于a[i]的元素全部出栈while(st.size()&&a[st.top()]<=a[i]) st.pop();
//此时栈顶元素存在,栈顶元素就是所求结果if(st.size()) ret[i]=st.top();
st.push(i);}
寻找当前元素右侧,离它最近,并且比它大的元素在哪
改成for(int i = n;i>=1;i--)
寻找当前元素左侧,离它最近,并且比它小的元素在哪
int a[N]里面存数(已存好)
ret里面存的答案
stack<int>st;//维护一个单调递增的栈,里面存的是下标
for(i=1;i<=n;i++)
{
//栈里面大于等于a[i]的元素全部出栈
while(st.size()&&a[st.top()]>=a[i])st.pop();//这里的符号是跟上面的唯一区别
//此时栈顶元素存在,栈顶元素就是所求结果
if(st.size()) ret[i]=st.top();
st.push(i);}
寻找当前元素右侧,离它最近,并且比它小的元素在哪
把上面改为for(int i=n;i>=1;i--)即可//n次逆遍历可以记一下是这个
总结:
找左侧,正遍历;找右侧,逆遍历;
比它大,单调减;比它小,单调增。//构造___栈
例题: 洛谷  P1901 发射站

洛谷 P1901 发射站

单调队列

是一个存单调元素的双端队列

应用:解决滑动窗口内的最大值最小值问题

(前面基础算法的滑动窗口不是用来求其中的最值的)

洛谷 P1886 滑动窗⼝ /【模板】单调队列

例题:洛谷  P1886 滑动窗⼝ /【模板】单调队列
int a[N]里面存的元素(已存好)
窗口内最大值:
从左往右遍历元素,维护一个单调递减的双端队列
当前元素进队之后,注意维护队列内的元素在大小为k的窗口内
此时队头元素就是最大值
代码:
deque<int>q;//存下标
for(int i = 1;i<=n;i++)
{while(q.size()&&a[q.back()]<=a[i])q.pop_back();
q.push_back(i);
if(q.back()-q.front()+1>k) q.pop_front();
if(i>=k)cout<<a[q.front()]<<" ";}窗口内最小值:
从左往右遍历元素,维护一个单调递增的双端队列
当前元素进队之后,注意维护队列的元素在大小为k的窗口内
此时队头元素就是最小值

并查集

并查集是一种用于维护元素所属集合的数据结构,用双亲表示法来实现

应用eg:维护连通块的信息

相关的一些概念:

查询操作:查找元素x属于哪一个集合,一般会在每个集合中选取一个元素作为代码,查询的是这个集合中的代表元素

合并操作:将元素x所在的集合与元素y所在的集合合并成一个元素

(注意:合并的是元素所属的集合,而并非单单两个元素)

判断操作:判断元素x和y是否在同一个集合

洛谷 P1551 亲戚

并查集的实现:
例题:洛谷  P1551 亲戚
1.初始化:让元素自己指向自己即可
int fa[N];一般并查集用fa来表示
for(int i=1;i<=n;i++) fa[i] = i;2.查询操作:就是一直向上"找爸爸"(这个find可以多次使用)
int find(int x)//查询x所在集合的代表元素是谁
return fa[x] == x?x:find(fa[x]);//是x就返回x,不是就find(fa[x])3.合并操作:(重复合并不会出错)
让元素x所在集合的代表元素指向元素y所在集合的代表元素
void un(int x,int y)
{ int fx = find(x);int fy = find(y);fa[fx] = fy;}4.判断操作
看看两者所在集合的总代表元素是否相同
bool issame(int x,int y)
{return find(x) == find(y);}

扩展域并查集

元素之间存在多种关系比如:朋友和敌人 而不像上面只存在:亲戚这样一种关系的话,就要用扩展域并查集

和普通并查集的区别:将每个元素拆分成多个域,每个域代表⼀种状态或者关系

洛谷 P1892 [BOI2003] 团伙

例题:洛谷  P1892 [BOI2003] 团伙
这里只写不同点:
find和un与上面的写法一模一样
//两种关系,所以N*2:x的母敌人是x+n
int fa[N*2];
//初始化:
for(int i=1;i<=n*2;i++) fa[i]=i;
while(m--)//m是题目中的"m个关系"
{if(op == 'F')  un(x,y);else//敌人,读取的是y和x是敌人关系{//存法:这俩都得写,少一个都不行un(x,y+n);//这两是朋友关系un(y,x+n);//这两是朋友关系}
}

带权并查集

概念:就是在普通并查集的基础上,为每个结点增加一个权值。这个权值可以表示当前结点与父结点之间的信息(因为find那我们用的路径压缩,因为最终这个权值是当前结点相对于根节点的信息)

洛谷 P1196 [NOI2002] 银河英雄传说

带权并查集的一些操作:(这里的d[N]以到父结点的距离为例)
例题:洛谷  P1196 [NOI2002] 银河英雄传说
新加了一个d[N]1.初始化:
多初始化个d[i]即可2.查询操作:(对这种代码来说,一个结点只能进行一次这种find操作!)
int find(int x)
{ if(fa[x]==x) return x;int t = find(fa[x]);//这一步要先搞d[x]+=d[fa[x]];//不为距离时可能会变为其他
return fa[x] = t;//完成路径压缩
}3.合并操作://x所在集合与y所在集合合并,x与y之间的权值是w
void un (int x,int y, int w)
{int fx = find(x),fy = find(y);
if(fx!=fy){fa[fx] = fy;d[fx]= d[y]+w-d[x]; //可能会变,这里是拿距离举例的} }4.查询操作://查询y与x之间的距离
int query(int x,int y)
{int fx = find(x),fy = find(y);
//如果不在同一个集合中,说明距离未知(具体返回什么要看题意)if(fx!=fy)return 0x3f3f3f3f;
return d[y]-d[x];
}

字符串哈希

一般利用前缀和思想去预处理字符串汇总每个前缀的哈希值

(使用前提:需要多次询问一个字符串的子串的哈希值)

核心思想:把字符串映射成P进制数字

P一般选择13331或者131

字符串哈希的作用:

字符串哈希一般用于判断两个字符串及其各子串是否相等

(和字典树的区别是这个字符串哈希侧重于判断功能)

洛谷 P10468 兔⼦与兔⼦

例题:洛谷  P10468 兔⼦与兔⼦
前缀字符串哈希模板:
typedef unsigned lon long ULL;
P = 13331;
int len;
string s;//一般都要搞一下s = ' '+s;来让i从1开始搞
ULL f[N];//前缀哈希数组
ULL p[N];//记录P的i次方->p[i]为P的i次方
//处理前缀哈希数组以及P的i次方数组
void init_hash()
{f[0] = 0;p[0] = 1;for(int i = 1;i<=len;i++){ f[i]=f[i-1]*P+s[i];p[i]=p[i-1]*P;} }
//快速求得任意区间的哈希值
ULL get_hash(int l,int r)
{return f[r]-f[l-1]*p[r-l+1];}如果题目只是简单的求单个字符串的哈希值:
ULL gethash()
{ULL ret = 0;for(int i =1;i<=len;i++){ret = ret*p+s[i];} return ret;}

Trie树(又叫字典树或前缀树)

是一种能够快速插入和查询字符串的数据结构

理解:我们可以把字典树想象成一颗多叉树,每一条边代表一个字符,从根节点到某个节点的路径就代表了一个字符串

作用:

1.查询某个单词是否出现过,并且出现几次

2.查询有多少个单词是以某个字符串为前缀

3.查询所有以某个前缀开头的单词

字典树的实现:
默认需要存的全是小写字母1.准备工作int tree[N][26],p[N],e[N];//N一般令为所有字符串中一共有多少个字符
// p[i]表示第i个被开辟的点被经过了多少次,
//e[i]表示以第i个被开辟的点为结尾的有多少个
int idx;2.插入字符串
void insert(string&s)
{int cur = 0;//从根节点开始p[cur]++;//这个格子经过一次for(auto ch:s){
//这个path的表达式常改!!!依据题意改int path = ch - 'a';//如果没有路if(tree[cur][path] == 0) tree[cur][path]= ++idx;cur = tree[cur][path];p[cur]++ }e[cur]++;
}3.查询字符串出现的次数:
int find(string&s)
{int cur = 0;for(auto ch:s){int path = ch - 'a';if(tree[cur][path] == 0) return 0;cur = tree[cur][path];} return e[cur];}4.查询有多少个单词以字符串s为前缀:int find_pre(string&s)
{int cur = 0;for(auto ch:s){int path = ch-'a';if(tree[cur][path] == 0) return 0;cur = tree[cur][path];} return p[cur];}例题:洛谷  P2580 于是他错误的点名开始了

洛谷 P2580 于是他错误的点名开始了

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

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

相关文章

【AI学习】初步了解Gradio

Gradio 是一个开源的 Python 库&#xff0c;专注于快速构建交互式 Web 界面&#xff0c;特别适用于机器学习模型、数据科学项目或任意 Python 函数的演示与部署。它通过极简的代码实现前后端一体化&#xff0c;无需前端开发经验即可创建功能丰富的应用。以下是 Gradio 的核心特…

Overleaf 论文提交 Arxiv

Contents References 清除 Overleaf 中所有编译 error&#xff0c;并且保证 main.tex 文件在 project 最上层参考文件 .bib 转 .bbl. project 编译成功后可以在 Overleaf 的 Recompile 按钮右侧找到 “Logs and output files”&#xff0c;点进去之后右下角可以点开 “Other lo…

【Android Audio】Parameter Framework - pfw

Parameter Framework - Android AudioPolicy Engine 使用 libengineconfigurable.so 来取缔默认安卓音频引擎 libenginedefault.so&#xff0c;因为默认安卓音频引擎是通过代码来决定策略&#xff0c;然而 libengineconfigurable 采用读取pfw类型的文件来实现音频策略配置。 …

服务器虚拟化技术深度解析:医药流通行业IT架构优化指南

一、服务器虚拟化的定义与原理 &#xff08;一&#xff09;技术定义&#xff1a;从物理到虚拟的资源重构 服务器虚拟化是通过软件层&#xff08;Hypervisor&#xff09;将物理服务器的CPU、内存、存储、网络等硬件资源抽象为逻辑资源池&#xff0c;分割成多个相互隔离的虚拟机…

babel-runtime 如何缩小打包体积

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&#…

剑指Offer(数据结构与算法面试题精讲)C++版——day7

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day7 题目一&#xff1a;最多删除一个字符得到回文题目二&#xff1a;回文子字符串的个数题目三&#xff1a;删除倒数第k个节点 题目一&#xff1a;最多删除一个字符得到回文 这里我们可以在经典的字符串回文…

2025年常见渗透测试面试题(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 常见面试题 一、渗透测试经历与技术复盘 二、高频漏洞类型与攻防体系 三、渗透工具链与技术特性 四、…

大数据与人工智能之大数据架构(Hadoop、Spark、Flink)

一、核心特性与架构设计 1. Hadoop&#xff1a;分布式批处理的基石 核心组件&#xff1a; HDFS&#xff1a;分布式文件系统&#xff0c;支持大规模数据存储。MapReduce&#xff1a;基于“分而治之”的批处理模型&#xff0c;适合离线分析。 架构特点&#xff1a; 批处理主导&…

从IoT到AIoT:智能边界的拓展与AI未来趋势预测

文章目录 引言&#xff1a;从连接万物到感知万物1. AIoT的本质&#xff1a;将智能嵌入万物2. AIoT的推动力量与挑战2.1 推动力量2.2 关键挑战 3. 五大AIoT未来趋势预测趋势一&#xff1a;边缘智能将成为主流架构趋势二&#xff1a;AI模型将向自适应与多任务演进趋势三&#xff…

从本地新建文件夹到拉取远程仓库 dev 分支的完整步骤

《从本地新建文件夹到拉取远程仓库 dev 分支的完整步骤》 下面为你详细介绍从本地新建文件夹开始&#xff0c;将远程仓库的 dev 分支拉取到本地的具体步骤&#xff1a; 1. 创建新文件夹 在本地电脑上新建一个文件夹&#xff0c;作为存放项目代码的目录。你可以通过图形界面操…

python/pytorch杂聊

Dataset 是否需要自己定义&#xff1a;如果你使用的数据集不是 PyTorch 提供的标准数据集&#xff08;如 MNIST、CIFAR-10 等&#xff09;&#xff0c;那么你需要继承 torch.utils.data.Dataset 类并实现两个方法&#xff1a;__len__() 和 __getitem__()。__len__() 应该返回数…

PHP 安全 E-mail

PHP 安全 E-mail 引言 随着互联网的普及和电子商务的发展,电子邮件成为了人们日常生活中不可或缺的通信工具。PHP作为一种广泛使用的服务器端脚本语言,也经常被用于发送和接收电子邮件。然而,在PHP中处理电子邮件时,安全性问题不容忽视。本文将深入探讨PHP安全发送电子邮…

【夜话系列】DelayQueue延迟队列(下):实战应用与面试精讲

🔥 本文是DelayQueue系列的下篇,聚焦实战应用场景和性能优化。通过多个真实案例,带你掌握DelayQueue在项目中的最佳实践和性能调优技巧。 📚 系列专栏推荐: JAVA集合专栏 【夜话集】JVM知识专栏数据库sql理论与实战小游戏开发文章目录 一、DelayQueue实战应用1.1 订单超…

Redis(笔记)

简介&#xff1a; 常用数据类型: 常用操作命令&#xff1a; Redis的Java客户端&#xff1a; 操作字符串类型的数据&#xff1a; 操作Hash类型的数据&#xff1a; 操作列表类型的数据&#xff1a; 操作集合类型的数据&#xff1a; 操作有序集合类型数据&#xff1a; 通用命令…

PhotoShop学习05

1.选区基础知识 选区&#xff0c;就是选定一些区域&#xff0c;我们对图片的更改只在选区内生效&#xff0c;这样可以精细调整图片的部分而不会影响整体。它的快捷键是M。 我们用点击鼠标后滑动就会出现虚线框&#xff0c;虚线框内的就是我们选定的区域。这时我们再滑动就会创…

使用Redission实现分布式锁

分布式锁在分布式系统中非常重要&#xff0c;主要用于解决多个进程/服务并发访问共享资源时的数据一致性问题。在日常开发中常用于&#xff1a; 1. 防止重复操作&#xff08;幂等性控制&#xff09; 场景&#xff1a;用户重复提交订单、重复支付、重复点击等。 示例&#xff1…

VScode 画时序图(FPGA)

1、先安装插件&#xff1a; 2、然后就可以编写一个.js文件&#xff0c;如下&#xff1a; {signal: [{name: clk, wave: p.......|..},{name: rstn, wave: 01......|..},{name: din_vld, wave: 0.1.0...|..},{name: din, wave: "x.x...|..", data: ["D0", …

嵌入式学习笔记——I2C

IIC协议详解 一、IIC协议简介二、IIC总线结构图三、IIC通信流程详解1. 空闲状态 : 双高空闲2. 起始信号&#xff08;START&#xff09;: 时高数下开始3. 停止信号&#xff08;STOP&#xff09;: 时高数上结束4. 数据传输格式 : 时高数稳&#xff0c;时低数变5. 应答信号 四、写…

Apifox Helper 与 Swagger3 区别

核心定位差异 Apifox Helper 定位&#xff1a;基于 IDEA 的代码注释解析工具&#xff0c;与 Apifox 平台深度集成&#xff0c;实现文档自动生成接口管理测试协作的一体化流程。 特点&#xff1a; 通过解析 Javadoc、KDoc 等注释生成文档&#xff0c;代码零侵入&#xff08;无…

单片机实现多线程的方法汇总

在单片机上实现“多线程”的方法有几种&#xff0c;下面按照从简单到复杂、从轻量到系统性来列出常见的方案&#xff1a; &#x1f9f5; 一、伪多线程&#xff08;最轻量&#xff09; 方法&#xff1a;主循环 状态机 / 定时器轮询 主循环中轮流调用各个任务的处理函数&#x…