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

news/2024/11/8 15:08:19/

今天我们一起来做一道关于队列的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.ppmy.cn/news/1251731.html

相关文章

Selenium 连接到现有的 Google Chrome 示例

python 3.7 selenium 3.14.1 urllib3 1.26.8 Google Chrome 119.0.6045.160 (64位) chromedriver.exe 119.0.6045.105(win32) 1 Google Chrome 添加参数 "--remote-debugging-port9222" 2 测试效果(chromedriver.exe 要和 Google Chrome 版本…

Java小游戏:飞翔的小只因

一、项目分析 创建一个窗口和画板,把画板放到窗口上,在画板上绘画图片 (2)让小鸟在画面中动起来,可以上下飞 (3)让地面和管道动起来 (4)碰撞检测 (5&#xf…

zerotier 搭建 moon中转服务器 及 自建planet

搭建moon 服务器 环境准备 # 安装依赖 yum install wget gcc gcc-c git -y yum install json-devel -y# 下载及安装 curl -s https://install.zerotier.com/ | sudo bash节点ID 配置 配置moon.json文件 cd /var/lib/zerotier-one/# 导出依赖 zerotier-idtool initmoon ide…

第十三章 python之爬虫

Python基础、函数、模块、面向对象、网络和并发编程、数据库和缓存、 前端、django、Flask、tornado、api、git、爬虫、算法和数据结构、Linux、设计题、客观题、其他 第十三章 爬虫 1. 写出在网络爬取过程中, 遇到防爬问题的解决办法。 在网络爬取过程中,可能会遇…

Vue学习笔记-模块化+命名空间

目的 让代码更好维护,让多种数据分类更加明确(不同的模块挤在一个index.js中显得臃肿且不方便管理) 实现方式 修改store/index.js(也可以将不同模块分别写在不同的js文件中) const countAbout {//开启命名空间namespaced:true,actions:{..…

Mendix组件推荐:灵活的在线表格

- 视频 mendix在线表格.mp4 20.95MB - 客户需求 如果你是一个中小型企业的负责人,你可能面临着: 多人协作录入数据展示数据库中的数据对数据安全有要求、希望本地离线部署并且IT人员配置有限等挑战 为了更好地管理你的业务数据,你需要一个…

reversed函数(python)

在Python中,reversed()是一个内置函数,用于将序列(如字符串、列表、元组等)进行反转。它返回一个反向迭代器对象,可以使用list()函数将其转换为一个列表。 语法: reversed(sequence)参数: se…

拼图 游戏

运行出的游戏界面如下:按住A不松开,显示完整图片;松开A显示随机打乱的图片 User类 package domain;/*** ClassName: User* Author: Kox* Data: 2023/2/2* Sketch:*/ public class User {private String username;private String password;p…