力扣OJ题讲解——循环队列

今天我们一起来做一道关于队列的OJ题目,这是力扣题目622题,点击题目链接可以直接跳转,https://leetcode.cn/problems/design-circular-queue/

首先,我们看到要求,需要我们实现哪些功能? 

 我们需要设置队列长度K,队首元素,队尾元素,插入元素,删除元素,判断空,判断满。那这么多接口,我们要从哪里入手呢?我们现在做题无外乎要么用顺序表的方式,要么用链表的方式,使用两者其实都可以,今天我们就用顺序表的方式实现吧。既然使用顺序表也就是数组,那么我们要考虑一点,在什么情况下这个队列为空?要确定这个循环队列为空,那就需要保证,头元素的下标和尾元素的下标相等才可以,假设我们设头元素下标为front,back为尾元素下一个位置,因为我们要区分back=0时,到底是有一个元素还是没有元素的情况。即要保证front=back时,队列为空。

考虑了队列为空的情况,那什么时候循环队列满了呢?满了就是已经不能再放其它元素,也就是尾位置,back就要追上front了,也就是back=front吗?那我们想一想,队列为空的时候和队列为满的时候,都是front=back,我们要怎么区分这两种情况呢?

我们不妨设置队列长度K的时候多开一个空间,即k+1,我们保证k+1个空间最多只使用k个,留出一个位置,让back+1=front时为满队列。这样就能区分队列满和队列空的情况了。

下来我们开始做题。

typedef struct {int *a;//数组int front;//队首元素下标int back;//队尾元素下标的下一个位置int k;//队列大小
} MyCircularQueue;

我们定义完结构体变量下来需要对结构题的成员初始化,即

MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=0;obj->back=0;obj->k=k;return obj;}

为什么我们要给开k+1个空间呢?原因我们在上面讲过了,就是为了让队列满的情况时back+1=front。

下来我们先把容易实现的接口先完成,先把什么时候为空,什么时候为满实现。

为空

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front==obj->back;
}

为满

bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->back+1=obj->front;//这样做合适吗?
}

 我们要考虑到,这是一个循环队列,下面这种情况能满足吗?

back要一直往后走吗? 显然不是,这是一个循环队列,当back走到k时,下一次就要回到起点,那怎么表示呢?我们不妨这样表示,(obj->back+1)%(obj->k+1)==obj->front,这个队列一共有k+1个空间,我们知道,如果一个小的数%一个比自己大的数是不会改变值的,所以,如果back+1=k+1,此时,back就要回到起点了。所以判断队列满我们可以这样写

bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->back+1)%(obj->k+1)==obj->front;
}

 下面我们写插入接口

这是一个bool类型,也就是要返回true和false,那什么时候要返回false呢?注意这是往队列插入元素,如果队列已经满了,我们就插不了元素了。剩下就可以正常插入了,直接让obj->a[obj->back]=value即可,再让obj->back++。注意到这里,我们还要需要检查back有没有超过队列空间的大小,即我们需要在后面让obj->back%=obj->k+1;即

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj))return false;obj->a[obj->back]=value;obj->back++;obj->back=(obj->back)%(obj->k+1);return true;
}

队列删除

删除接口同样是bool类型,我们要判断什么时候删除失败?当然就是队列为空的时候删除失败,我们要先检查队列是否为空,再删除,删除非常简单,直接让front++就可以了,front一直在++,有没有可能front也会超出队列的空间大小?当然有可能,所以我们也需要对front检查一下,即obj->front%=obj->k+1;

bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return false;obj->front++;obj->front=(obj->front)%(obj->k+1);return true;
}

下面就是返回对头元素

题目里说了,如果队列为空就返回-1,这种情况我们也要处理一下,其余就直接返回obj->a[obj->front]即可。

int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[obj->front];
}

 队尾元素

同样我们也要处理一次队列为空返回-1的情况,然后直接返回obj->a[obj->back-1]可以吗?

我们思考一下,如果back=0呢?我说的不是队列为空时,因为为空时我们已经处理了,我说的时当back已经走了至少一轮重新回到起点的情况,此时的back-1就成-1了,那我们怎么处理呢?我们要知道,这种情况下的back时已经被取模了k+1后,那我们不妨可以给back-1+k+1再给它取模k+1;即(obj->back-1)+(obj->k+1)%(obj->k+1);怎么理解这个公式,还是那句话,back-1不可能大于k+1,一个数%比他小的数值不变,(a+b)%b,如果a比b小且a是正数,那这个值是不变的,这一种情况也就对应了我们此处back!=0的情况,如果back=0,尾元素就在k的位置,那back-1就是-1,他再加上k+1再%k+1要比k+1小,所以结果就是k那个位置。

int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))return -1;return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];
}

到这里这道题就大功告成了,此时我们运行,报了一个这样错误

是因为,我们在前面调用了就很多次队列为空为满的情况,也没有声明,所以我们可以把判断队列为空,为满挪到插入接口前面就可以啦。

好啦,本次题目就到这里了,希望大家能够多多支持,我们下次再见!

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

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

相关文章

经典双指针算法试题(二)

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、有效三角形的个数1、题目讲解2、讲解算法原理3、代码实现 二、查找总价格为目标值的两个商…

Hutool

一、简介 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅 官方文档: https://www.hutool.cn/docs/#/ 二、包含组件 一个Java基础工具类,对文…

allegro画封装时使用坐标指令无效

使用坐标指令时显示:“Pick is outside the extent of the drawing…pick again” 这是因为你放的引脚已经超出你这个绘制界面的定义尺寸,需要到Setup->Design pararmeters…里面去将图幅改大一点,如下图所示: 然后点击Design…

消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!

前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ?RabbiMQ的高性能之道是如何做到的?什么是AMQP高级协议?AMQP核心概念是什么?RabbitMQ整体架构模型是什么样子的?Rabbi…

P8599 [蓝桥杯 2013 省 B] 带分数(dfs+全排列+断点判断)

思路&#xff1a;1.深度枚举所有排列情况 2.设置为每个排列设置两个断点&#xff0c;分为三部分&#xff1a;a,b,c 3.转换为乘法判断条件&#xff0c;满足加一 代码如下&#xff1a;&#xff08;可用next_permutation全排列函数代替dfs&#xff09; #include<iostream>…

全面的日志监控管理工具

企业网络由众多日志源组成。集中监控这些日志源有助于防止数据威胁和网络攻击&#xff0c;综合日志监控解决方案可以自动执行日志管理流程&#xff0c;通过关联日志来识别恶意活动&#xff0c;并帮助满足IT合规性要求。 不同类型的日志监控 EventLog Analyzer 综合日志监控解…

智慧法院档案数字化解决方案

智慧法院档案数字化解决方案可以采用以下步骤&#xff1a; 1. 确定数字化目标&#xff1a;明确数字化的目标和范围&#xff0c;比如将所有的案件相关文件、纸质档案和材料进行数字化。 2. 确定数字化流程&#xff1a;制定数字化的流程和标准&#xff0c;比如采用哪些设备和软件…

【C语言】qsort函数

目录 简介 头文件 ​编辑 函数原型&#xff1a; 参数函数如何写&#xff1a; 参数函数要求&#xff1a; qsort对整性数据的排序&#xff1a; qsort对字符型数据的排序&#xff1a; 对结构体类型的内部元素排序&#xff1a; 函数的底层是以快速排序实现的 但是本文不深入…

小黑子—Maven高级

Maven高级篇 二 小黑子的Maven高级篇学习1. 分模块开发1.1 分模块开发设计1.2 分模块开发实现1.2.1 抽取domain层1.2.2 抽取dao层 2. 依赖管理2.1 依赖传递2.2 可选依赖2.3 排除依赖 3. 继承与聚合3.1 聚合3.2 继承3.3 总结 4. 属性4.1 配置文件加载属性4.2 版本管理 5. 多环境…

【开源】基于Vue.js的民宿预定管理系统

项目编号&#xff1a; S 058 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S058&#xff0c;文末获取源码。} 项目编号&#xff1a;S058&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色…

梦开始的地方——Adobe Premiere Pro

今天&#xff0c;我们来说说一款老生常谈的相信也是很多人都经常迫切需要的软件。Adobe Premiere Pro&#xff0c;简称Pr&#xff0c;是由Adobe公司开发的一款视频编辑软件。 Premiere Pro是视频编辑爱好者和专业人士必不可少的视频编辑工具。它可以提升您的创作能力和创作自由…

httpd(Web服务器)

名词解释 1、URL&#xff1a;Uniform Resource Locator&#xff0c;统⼀资源定位符 2、⽹址格式&#xff1a;<协议>://<主机或主机名>[:port]/<⽬录资源,路径> 3、主机地址/主机名&#xff1a;主机地址是服务器在因特⽹所在的IP地址。主机名就需要域名解析…

装饰器设计模式是什么?什么是 Decorator 装饰器设计模式?Python 装饰器设计模式示例代码

什么是 Decorator 装饰器设计模式&#xff1f; 装饰器模式是一种结构型设计模式&#xff0c;它允许向现有对象动态地添加新功能&#xff0c;同时不改变其结构。这种模式实现了对对象的包装&#xff0c;称为装饰器&#xff0c;并且可以在运行时动态地添加、修改或删除对象的行为…

重磅!这本30w人都在看的Python数据分析畅销书:更新了!

想学习python进行数据分析&#xff0c;这本《利用python进行数据分析》是绕不开的一本书。目前该书根据Python3.10已经更新到第三版。 Python 语言极具吸引力。自从 1991 年诞生以来&#xff0c;Python 如今已经成为最受欢迎的解释型编程语言。 pandas 诞生于2008年。它是由韦…

NX二次开发UF_CAM_set_clear_plane_data 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_set_clear_plane_data Defined in: uf_cam_planes.h int UF_CAM_set_clear_plane_data(tag_t object_tag, double origin [ 3 ] , double normal [ 3 ] ) overview 概述 De…

快慢指针判断环形链表

我们在前面文章中写过用快慢指针判断链表是否带环&#xff1a; leetcode&#xff1a;环形链表-CSDN博客 我们用的是slow指针一次走一步&#xff0c;fast指针一次走两步&#xff0c;当slow入环后开始了追击&#xff0c;每走一次距离缩短1&#xff0c;最终就会相遇 思考问题 …

【LeetCode】每日一题 2023_11_23 HTML 实体解析器(调库/打工)

文章目录 刷题前唠嗑题目&#xff1a;HTML 实体解析器题目描述代码与解题思路 结语 刷题前唠嗑 题目&#xff1a;HTML 实体解析器 题目链接&#xff1a;1410. HTML 实体解析器 题目描述 代码与解题思路 func entityParser(s string) (ans string) {return strings.NewRepla…

NX二次开发UF_CAM_set_lower_limit_plane_tag 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_set_lower_limit_plane_tag Defined in: uf_cam_planes.h int UF_CAM_set_lower_limit_plane_tag(tag_t object_tag, tag_t target_tag ) overview 概述 Set the tag of a …

使用 PowerShell 创建共享目录

在 Windows 中&#xff0c;可以使用共享目录来将文件和文件夹共享给其他用户或计算机。共享目录可以通过网络访问&#xff0c;这使得它们非常适合用于文件共享、协作和远程访问。 要使用 PowerShell 创建共享目录&#xff0c;可以使用 New-SmbShare cmdlet。New-SmbShare cmdl…

算法的奥秘:常见的六种算法(算法导论笔记2)

算法的奥秘&#xff1a;种类、特性及应用详解&#xff08;算法导论笔记1&#xff09; 上期总结算法的种类和大致介绍&#xff0c;这一期主要讲常见的六种算法详解以及演示。 排序算法&#xff1a; 排序算法是一类用于对一组数据元素进行排序的算法。根据不同的排序方式和时间复…