leetcode 622. 设计循环链表
这道题讲了两种方法,第一个代码是用数组实现的,第二个是用链表实现的,希望对你们有帮助
(最好在VS自己测试一遍,再放到 leetcode上哦)
下面的是主函数(作参考),静下心来慢慢测试

622. 设计循环链表
题目
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
- MyCircularQueue(k): 构造器,设置队列长度为 k 。
- Front: 从队首获取元素。如果队列为空,返回 -1 。
- Rear: 获取队尾元素。如果队列为空,返回 -1 。
- enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
- deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
- isEmpty(): 检查循环队列是否为空。
- isFull(): 检查循环队列是否已满。
题目链接
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文字 和 画图 分析
- 思考什么情况下,队列为空,队列为满
定义一个 指针head,用来存放头节点的地址,和一个指针tail,用来存放尾节点的地址(这个思路和队列的实现是一样的)
按照正常思路,大多数人会以为(队列长度为k):
当 head = tail 为空,而 tail 是第 k 个节点的时候为满,却忽略一点,这是个循环链表
以下这种情况就不成立:
通过图我们知道 head = tail 无法判断是空还是满
所以我们换一种思路:
存放 k 个元素,但是开辟(k + 1)个节点,故意留下一个节点不放元素
情况就是这样的:
我们发现:
当 head = tail 为空;
当 tail 的下一个节点 = head为满;
2. 选用数组还是链表去做
这里两者思路我都讲(代码仅供参考,能通过,但是我个人觉得有些地方没有处理好,其实可以更完善,听思路即可)
- 用数组(head 和 tail 就是元素下标)
a. 首先明确这本质是一个循环链表
b. 实现过程可能会遇到的问题:
问题1:
这里可以看到 tail 不可能一直加加
如果是正确的思路,此时的图应该是这样:
所以我们这里要对 tail 进行处理:
这里可以通用
tail = tail % (k + 1)(head也会出现这样的情况,同样要这么处理)
问题2:
判断为满时,我们可能会犯错误
这种情况我们非常容易知道:判断
tail + 1 == head
但是这种情况就不适用了:
所以我们要写一个通式:
(tail + 1 ) % (k + 1) == head
问题3:
找到尾元素
正常情况下的尾元素很好找
尾元素的下标就是 tail - 1
如果是这样,就不好判断了
这里我们可以用 if ,else语句做区分,
也可以写一个通式:
(tail - 1 + k + 1) % (k + 1)
即:(tail + k )%(k + 1)
- 用链表(head 和 tail 就是头节点和 尾节点的地址)
a. 这里可以写一个循环链表
可以在初始化的时候先搭建好这个循环链表,后面再存放元素
b. 只有一个地方需要注意:
就是找尾元素(实际上,应该是tail的上一个节点)
这里选择可以记录上一个节点的地址
或者 循环找到上一个节点
代码
代码1:
typedef int SLType;
typedef struct StackList
{SLType* a;int top;int rear;int k;
}SL;//创建数组
void SLInit(SL* head, int k)
{assert(head);head->a = (SLType*)malloc((k + 1) * sizeof(SLType));head->top = 0;head->rear = 0;head->k = k;
}//初始化数组
void SLPush(SL* head, SLType x)
{assert(head);head->a[head->rear] = x;head->rear++;
}//存放元素
void SLPop(SL* head)
{assert(head);head->top++;
}//删除元素//以上都是数组的实现typedef struct
{SL q;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));SLInit(&obj->q, k);return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{SL* q1 = &obj->q;return q1->rear == q1->top;
}//判断是否为空bool myCircularQueueIsFull(MyCircularQueue* obj)
{SL* q1 = &obj->q;int a = q1->rear;a = (q1->rear + 1) % (q1->k + 1);return a == q1->top;
}//判断是否为满bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{if (myCircularQueueIsFull(obj)){return false;}else{SLPush(&obj->q, value);SL* q1 = &obj->q;q1->rear = q1->rear % (q1->k + 1);return true;}}//存放元素bool myCircularQueueDeQueue(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return false;}else{SLPop(&obj->q);SL* q1 = &obj->q;q1->top = q1->top % (q1->k + 1);return true;}}//删除元素int myCircularQueueFront(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return -1;}else{return (&obj->q)->a[(&obj->q)->top];}
}//返回头元素int myCircularQueueRear(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return -1;}else{if ((&obj->q)->rear == 0){return (&obj->q)->a[(&obj->q)->k];} return(&obj->q)->a[(&obj->q)->rear - 1];}
}//返回尾元素void myCircularQueueFree(MyCircularQueue* obj)
{free(obj);
}//销毁空间
代码2:
typedef int QLType;
typedef struct QueueNode
{QLType val;struct QueueNode* next;
}QN;//创建节点
typedef struct StackList
{QN* head;QN* tail;}QL;//创建队列
void QNInit(QL* pphead, int k)
{pphead->head = pphead->tail = NULL;QN* prev = NULL;k = k + 1;while (k--){QN* newnode = (QN*)malloc(sizeof(QN));if (pphead->head == NULL){prev = pphead->head = pphead->tail = newnode;}else{pphead->tail = newnode;pphead->head->next = pphead->tail;pphead->tail->next = prev;pphead->head = pphead->tail;}}pphead->head =pphead->tail = prev;
}//初始化并链接节点QLType QLTop(QL* pphead)
{return pphead->head->val;
}//返回首元素
QLType QLtail(QL* pphead)
{QN* rear = pphead->head;while (rear->next != pphead->tail){rear = rear->next;}return rear->val;
}//返回尾元素
void QLpush(QL* pphead, int val)
{pphead->tail->val = val;pphead->tail = pphead->tail->next;
}//存放元素
void QLPop(QL* pphead)
{pphead->head = pphead->head->next;
}//删除元素//以上是链表的创建typedef struct
{QL q;
} MyCircularQueue;MyCircularQueue * myCircularQueueCreate(int k)
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));QNInit(&obj->q, k);return obj;
}//初始化
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{QL* q1 = &obj->q;return q1->head == q1->tail;
}//判断是否为空bool myCircularQueueIsFull(MyCircularQueue* obj)
{QL* q1 = &obj->q;return q1->tail->next == q1->head;
}//判断是否为满
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{if (myCircularQueueIsFull(obj)){return false;}else{QLpush(&obj->q, value);return true;}}//存放元素bool myCircularQueueDeQueue(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return false;}else{QLPop(&obj->q);return true;}
}//删除元素int myCircularQueueFront(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return -1;}else{return QLTop(&obj->q);}
}//返回首元素int myCircularQueueRear(MyCircularQueue* obj)
{if (myCircularQueueIsEmpty(obj)){return -1;}else{return QLtail(&obj->q);}
}//返回尾元素void myCircularQueueFree(MyCircularQueue* obj)
{free(obj);
}//释放空间相关文章:
leetcode 622. 设计循环链表
这道题讲了两种方法,第一个代码是用数组实现的,第二个是用链表实现的,希望对你们有帮助 (最好在VS自己测试一遍,再放到 leetcode上哦) 下面的是主函数(作参考),静下心来…...
Linux:dockerfile编写搭建tomcat练习(9)
我使用的httpyum仓库 本地使用了5个文件,tomcat使用的官网解压直接用的包】 Dockerfile 主配置文件 基于centos基础镜像 jdk1.8.0_91 java环境 run.sh 启动脚本 centos.repo 仓库文件 tomcat 源码包 vim Dockerfile写入FROM centos MAINTAINER ta…...
Linux 基础IO
文章目录 前言基础IO定义系统IO接口文件描述符重定向原理缓冲区刷新 前言 要知道每个函数/接口的全部参数和返回值建议去官网或者直接在Linux的man手册中查,这不是复制粘贴函数用法的文章。 C语言文件读写介绍链接 基础IO定义 IO是Input/Output的缩写,…...
uniapp 打开文件管理器上传(H5、微信小程序、android app三端)文件
H5跟安卓APP 手机打开的效果图: Vue页面: <template><view class"content"><button click"uploadFiles">点击上传</button></view> </template><script>export default {data() {return…...
掌控安全 -- header注入
http header注入 该注入是指利用后端验证客户端口信息(比如常用的cookie验证)或者通过http header中获取客户端的一些信息(比如useragent用户代理等其他http header字段信息),因为这些信息是会重新返回拼接到后台中的&…...
windows批处理脚本(.bat)如何激活Anconda Prompt虚拟环境
通过call 来调用激活脚本, activate myenv指的是要激活的环境,若省略,则激活的是base环境。 call : 从另一个批处理程序调用一个批处理程序,而不停止父批处理程序。 call C:\ProgramData\Anaconda3\Scripts\activate.bat activate…...
扩散模型实战(十四):扩散模型生成音频
推荐阅读列表: 扩散模型实战(一):基本原理介绍 扩散模型实战(二):扩散模型的发展 扩散模型实战(三):扩散模型的应用 扩散模型实战(四ÿ…...
《微信小程序开发从入门到实战》学习四十七
4.4 云函数 4.4.5 云函数的定时触发 如果云函数需要定时执行,可以使用云函数定时触发器。配置了定时触发器,云函数会在相应时间点被自动触发。函数返回结果不会返回调用方 在需要添加触发器的云函数下新建文件config.json。格式如下: &quo…...
LeetCode刷题笔记之数组
一、二分查找 1. 704【二分查找】 题目: 给定一个 n 个元素 有序的(升序) 整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。代码:…...
ViT:视觉 Transformer
ViT:视觉 Transformer 网络结构Transformer 编码器MLP 头CNN 和 Transformer 网络结构 Transformer 的优势:注意力机制相当于一个多标签检索系统,位置嵌入能知道每个单词的位置,而且适合并行。 尝试把 Transformer 迁移到视觉领…...
Jmeter 请求签名api接口-BeanShell
Jmeter 请求签名api接口-BeanShell 项目签名说明编译扩展jar包jmeter 使用 BeanShell 调用jar包中的签名方法 项目签名说明 有签名算法的api接口本地不好测试,使用BeanShell 扩展jar 包对参数进行签名,接口签名算法使用 sha512Hex 算法。签名的说明如下…...
No suitable driver found for jdbc:mysql://localhost:3306(2023/12/7更新)
有两种情况: 压根没安装下载了但没设为库或方法不对 大多数为第一种情况: 一. 下载jdbc 打开网址选择一个版本进行下载 https://nowjava.com/jar/version/mysql/mysql-connector-java.html 二.安装jdbc 在项目里建一个lib文件夹 在把之前下载的jar文…...
word文档中数字格式转换(排版助手)
示例:李老师收入了234243.33元,产量3000公斤; 张老师收入了2324324元,产量45555公斤; 孙老师收入了600000元,产量2342公斤 王老师收入了1234443243元,产量1243142公斤。 1、数字批量转换成千…...
阿里云docker加速
文章目录 一、 阿里云镜像仓库配置二、配置加速1. CentOS2. Mac3. Windows注意 一、 阿里云镜像仓库配置 1.注册阿里云账号,并登陆到阿里云后台,进入控制台面板 2.进入控制台以后,找到左上方的三横的功能列表按钮,在弹出来的功能…...
Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现
0x01 产品简介 Panalog大数据日志审计系统定位于将大数据产品应用于高校、 公安、 政企、 医疗、 金融、 能源等行业之中,针对网络流量的信息进行日志留存,可对用户上网行为进行审计,逐渐形成大数据采集、 大数据分析、 大数据整合的工作模式…...
openGauss学习笔记-152 openGauss 数据库运维-备份与恢复-物理备份与恢复之PITR恢复
文章目录 openGauss学习笔记-152 openGauss 数据库运维-备份与恢复-物理备份与恢复之PITR恢复152.1 背景信息152.2 前提条件152.3 PITR恢复流程152.4 recovery.conf文件配置**152.4.1 归档恢复配置****152.4.2 恢复目标设置** openGauss学习笔记-152 openGauss 数据库运维-备份…...
PhpStorm基本配置及常用快捷键
重要Preference配置 激活服务器 http://jetbrains.tencent.click/http://owo.helphttp://idea.imsxm.com/http://www.0-php.com:10172017.3以上版本 JetBrains IDE 2017.3以上版本,激活检测机制变成了动态封禁域名,导致大部分域名激活被屏蔽了࿰…...
Autosar通信实战系列05-CanNM模块进阶常见问题思考
本文框架 前言1. UDS 0x28服务控制Nm报文收发后对状态机有影响?2. 节点网络启动后第一帧是否必须是网络管理报文?3. 主动唤醒后发送的第一帧报文为NM报文如何配置?4. CanNmMsgCycleOffset的使用场景?5. 什么情况下CBV中RepeatMessageRequest Bit置位?6. 主动(本地)唤醒与…...
Java中多态的一些简单理解
什么是多态 1.面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。 2.多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发…...
011 数据结构_哈希
前言 本文将会向你介绍哈希概念,哈希方法,如何解决哈希冲突,以及闭散列与开散列的模拟实现 1. 哈希概念 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...








