当前位置:网站首页>LeetCode 每日一题——622. 设计循环队列
LeetCode 每日一题——622. 设计循环队列
2022-08-03 08:01:00 【SK_Jaco】
1.题目描述
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。
示例:
MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1); // 返回 true
circularQueue.enQueue(2); // 返回 true
circularQueue.enQueue(3); // 返回 true
circularQueue.enQueue(4); // 返回 false,队列已满
circularQueue.Rear(); // 返回 3
circularQueue.isFull(); // 返回 true
circularQueue.deQueue(); // 返回 true
circularQueue.enQueue(4); // 返回 true
circularQueue.Rear(); // 返回 4
2.解题思路与代码
2.1 解题思路
这道题就是需要写一个双端队列,并且按照题目要求需要提供六个对外的方法,分别是获取头元素(Front)、获取尾元素(Rear)、入队(enQueue)、出队(deQueue)、对列是否为空(isEmpty)、对列是否已满(isFull)。既然是双端对列首先就会考虑到需要头尾两个变量来指向队列的队头和队尾,那么在初始化的时候就会使用 head 和 rear 两个变量,如果使用这两个变量指向头尾的话会让整个代码变得复杂,而且很容易把自己绕晕,比如在计算队列大小的时候。
我们可以看到队尾变量其实只有在入队和获取队尾元素的时候才会使用到,那么我们就可以不需要使用队尾变量,而是使用一个 size 变量来记录当前队列的大小,如果需要队尾的时候就使用 head 的位置加上队列长度 size 来确定队尾的位置。确定队尾位置就会出现两种情况:head+size 小于初始队列长度和 head+size 大于等于队列长度,处理方式如下:
- head+size 小于初始队列长度:此时直接队尾就是 head+size
- head+size 大于等于队列长度:此时队尾位置超出数组长度,那么队尾的位置就需要回到数组第一位开始往下数,即( head+size)% queue.length
通过上面的设定,题目规定需要实现的及方法就变得非常简单了:
- 获取头元素(Front):直接返回 head 位置元素
- 获取尾元素(Rear):根据上面提到的获取队尾元素位置的方法,返回即可
- 入队(enQueue):同样先获取到队尾位置,然后在队尾位置上插入新的元素
- 出队(deQueue):直接让 head 加一向后移动一位,此时队头就从新的位置开始,原来位置上的元素不动,入队时直接覆盖即可。需要注意如果 head 自增后等于数组长度,那么就需要回到头,从 0 位置开始
- 对列是否为空(isEmpty):因为我们维护了一个 size 变量记录队列中的元素,因此直接返回 size 是否为 0 就可以了不再需要复杂的计算
- 对列是否已满(isFull):同理判断 size 是否等于数组长度即可
2.2 代码
class MyCircularQueue {
int[] queue;
int head;
int size;
public MyCircularQueue(int k) {
queue = new int[k];
head = 0;
size = 0;
}
public boolean enQueue(int value) {
if (isFull()) {
return false;
}
int rear = head + size;
int index = rear >= queue.length ? rear % queue.length : rear;
queue[index] = value;
size++;
return true;
}
public boolean deQueue() {
if (isEmpty()) {
return false;
}
head = head + 1 == queue.length ? 0 : head + 1;
size--;
return true;
}
public int Front() {
if (isEmpty()) {
return -1;
}
return queue[head];
}
public int Rear() {
if (isEmpty()) {
return -1;
}
int rear = head + size;
int index = rear > queue.length ? rear % queue.length : rear;
return queue[index - 1];
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == queue.length;
}
}
2.3 测试结果
通过测试
3.总结
- 维护 size 变量记录队列长度可以简化很多代码
- 注意队尾和队头的边界
边栏推荐
猜你喜欢
随机推荐
Transformer、BERT、GPT 论文精读笔记
Redisson实现分布式锁
ArcEngine (2) loading the map document
解决移动端有纵向滚动条但是不能滚动的问题
Using pipreqs export requirements needed for the project. TXT (rather than the whole environment)
Windows安装MySQL(MIS)
VR全景市场拓展技巧之“拓客宝典”
ArcEngine(三)通过MapControl控件实现放大缩小全图漫游
The Transformer, BERT, GPT paper intensive reading notes
智能客服,还有多少AI泡沫?
Nanny level explains Transformer
mysql的innodb存储引擎和myisam存储引擎的区别
最佳高质量字体
“唯一索引允许为空“ 的说法是不严谨的
Daily practice of PMP | Do not get lost in the exam-8.2 (including agility + multiple choice)
差分(前缀和的逆运算)
HCIA实验(07)
Karatsuba大数乘法的Verilog实现
五、《图解HTTP》报文首部和HTTP缓存
数仓4.0(二)------ 业务数据采集平台