622. 设计循环队列
622. 设计循环队列
题目
Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. It is also called "Ring Buffer".
One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.
Implementation the MyCircularQueue
class:
MyCircularQueue(k)
Initializes the object with the size of the queue to bek
.int Front()
Gets the front item from the queue. If the queue is empty, return-1
.int Rear()
Gets the last item from the queue. If the queue is empty, return-1
.boolean enQueue(int value)
Inserts an element into the circular queue. Returntrue
if the operation is successful.boolean deQueue()
Deletes an element from the circular queue. Returntrue
if the operation is successful.boolean isEmpty()
Checks whether the circular queue is empty or not.boolean isFull()
Checks whether the circular queue is full or not.
You must solve the problem without using the built-in queue data structure in your programming language.
Example 1:
Input
["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 3, true, true, true, 4]
Explanation
MyCircularQueue myCircularQueue = new MyCircularQueue(3);
myCircularQueue.enQueue(1); // return True
myCircularQueue.enQueue(2); // return True
myCircularQueue.enQueue(3); // return True
myCircularQueue.enQueue(4); // return False
myCircularQueue.Rear(); // return 3
myCircularQueue.isFull(); // return True
myCircularQueue.deQueue(); // return True
myCircularQueue.enQueue(4); // return True
myCircularQueue.Rear(); // return 4
Constraints:
1 <= k <= 1000
0 <= value <= 1000
- At most
3000
calls will be made toenQueue
,deQueue
,Front
,Rear
,isEmpty
, andisFull
.
题目大意
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
- MyCircularQueue(k): 构造器,设置队列长度为 k 。
- Front: 从队首获取元素。如果队列为空,返回 -1 。
- Rear: 获取队尾元素。如果队列为空,返回 -1 。
- enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
- deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
- isEmpty(): 检查循环队列是否为空。
- isFull(): 检查循环队列是否已满。
解题思路
- 设计一个环形队列,底层用数组实现;
- 额外维护 4 个变量,队列的总 size ,队头下标 head ,队尾下标 tail ;
- 每此入队和出队都更新 head , tail ,下标需要对 size 取余,因为超过 size 大小之后,需要循环存储;
代码
/**
* @param {number} k
*/
var MyCircularQueue = function (k) {
this.queue = new Array(k);
this.head = 0;
this.tail = 0;
this.size = k;
};
/**
* @param {number} value
* @return {boolean}
*/
MyCircularQueue.prototype.enQueue = function (value) {
if (this.isFull()) return false;
this.queue[this.tail] = value;
// 将 tail 指向队尾的下一个空间
this.tail = (this.tail + 1) % this.size;
return true;
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.deQueue = function () {
if (this.isEmpty()) return false;
this.queue[this.head] = null;
// 将 head 指向新的队头
this.head = (this.head + 1) % this.size;
return true;
};
/**
* @return {number}
*/
MyCircularQueue.prototype.Front = function () {
return this.isEmpty() ? -1 : this.queue[this.head];
};
/**
* @return {number}
*/
MyCircularQueue.prototype.Rear = function () {
// 因为 tail 指向队尾的下一个空间,所以要分情况处理
// 若 tail == 0,那队尾应该在 size - 1
// 其他情况,队尾在 tail - 1
let index = this.tail === 0 ? this.size - 1 : this.tail - 1;
return this.isEmpty() ? -1 : this.queue[index];
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.isEmpty = function () {
// head == tail 时,有两种情况
// 一种是队列为空,此时 queue[head] 为null
// 一种是队列满了,此时 queue[head] 有值
return this.head === this.tail && !this.queue[this.head];
};
/**
* @return {boolean}
*/
MyCircularQueue.prototype.isFull = function () {
return this.head === this.tail && !!this.queue[this.head];
};
相关题目
题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
---|---|---|---|---|---|
641 | 设计循环双端队列 | [✓] | 设计 队列 数组 1+ | 🟠 | 🀄️ 🔗 |
1670 | 设计前中后队列 | 设计 队列 数组 2+ | 🟠 | 🀄️ 🔗 |