题目
(1)设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
(2)循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间(假溢出)。但是使用循环队列,我们能使用这些空间去存储新的值。
(3)你的实现应该支持如下操作:
- MyCircularQueue(k): 构造器,设置队列长度为 k 。
- Front: 从队首获取元素。如果队列为空,返回 -1 。
- Rear: 获取队尾元素。如果队列为空,返回 -1 。
- enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
- deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
- isEmpty(): 检查循环队列是否为空。
- isFull(): 检查循环队列是否已满。
(4)示例如下:
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
解决思路
- 使用数组实现队列的功能。
- 定义head指向第一个元素,定义tail指向最后一个元素的下一个位置,定义cnt记录队列中的元素个数。
代码
- C++代码
# include <stdio.h>
#include <vector>
using namespace std;
class MyCircularQueue{
public:
vector<int> arr; // 创建一个动态数组,使用数组实现队列。
int head; // 指向队列的首位。
int tail; // 指向最后一个元素的下一个位置。
int cnt; // 记录队列中元素的个数。
MyCircularQueue(int k): arr(k), head(0), tail(0), cnt(0) {}
// 入队
bool enQueue(int value) {
if (isFull()) {
return false;
}
arr[tail] = value;
tail = (tail + 1) % arr.size();
cnt += 1;
return true;
}
// 出队
bool deQueue() {
if (isEmpty()) {
return false;
}
head = (head + 1) % arr.size();
cnt -= 1;
return true;
}
// 判断队列是否为空
bool isEmpty() {
return 0 == cnt;
}
// 判断队列是否已满
bool isFull() {
return arr.size() == cnt;
}
// 获取队首元素
int Front() {
if (isEmpty()) {
return -1;
}
return arr[head];
}
// 获取队尾元素
int Rear() {
if (isEmpty()) {
return -1;
}
// tail-1对应的元素才是最后一个元素。
// tail - 1 + arr.size()是为了防止tail=0时,tai-1成为负数,导致访问越界。
return arr[(tail - 1 + arr.size()) % arr.size()];
}
};
int main() {
int k = 3; // 设置长度为 3
MyCircularQueue *circularQueue = new MyCircularQueue(k);
printf("%d\n", circularQueue->enQueue(1)); // 返回 true
printf("%d\n", circularQueue->enQueue(2)); // 返回 true
printf("%d\n", circularQueue->enQueue(3)); // 返回 true
printf("%d\n", circularQueue->enQueue(4)); // 返回 false,队列已满
printf("%d\n", circularQueue->Rear()); // 返回 3
printf("%d\n", circularQueue->isFull()); // 返回 true
printf("%d\n", circularQueue->deQueue()); // 返回 true
printf("%d\n", circularQueue->enQueue(4)); // 返回 true
printf("%d\n", circularQueue->Rear()); // 返回 4
return 0;
}
- python代码
# -*- coding: utf-8 -*-
class MyCircularQueue:
def __init__(self, k: int):
self.arr = [-1 for i in range(k)] # 创建一个list实现队列。
self.size = k # 记录队列的大小。
self.head = 0 # 指向队列的首位。
self.tail = 0 # 指向最后一个元素的下一个位置。
self.cnt = 0 # 记录队列中元素的个数。
# 入队
def enQueue(self, value: int):
if self.isFull():
return False
self.arr[self.tail] = value
self.tail = (self.tail + 1) % self.size
self.cnt += 1
return True
# 出队
def deQueue(self):
if self.isEmpty():
return False
self.head = (self.head + 1) % self.size
self.cnt -= 1
return True
# 获取队首元素
def Front(self):
if self.isEmpty():
return -1
return self.arr[self.head]
# 获取队尾元素
def Rear(self):
if self.isEmpty():
return -1
# tail - 1对应的元素才是最后一个元素。
# tail - 1 + self.size()是为了防止tail = 0时,tai - 1成为负数,导致访问越界。
return self.arr[(self.tail - 1 + self.size) % self.size]
# 判断队列是否为空
def isEmpty(self):
return 0 == self.cnt
# 判断队列是否已满
def isFull(self):
return self.cnt == self.size
def main():
k: int = 3
circularQueue: MyCircularQueue = MyCircularQueue(k)
print(circularQueue.enQueue(1)) # 返回 true
print(circularQueue.enQueue(2)) # 返回 true
print(circularQueue.enQueue(3)) # 返回 true
print(circularQueue.enQueue(4)) # 返回 false,队列已满
print(circularQueue.Rear()) # 返回 3
print(circularQueue.isFull()) # 返回 true
print(circularQueue.deQueue()) # 返回 true
print(circularQueue.enQueue(4)) # 返回 true
print(circularQueue.Rear()) # 返回 4
if __name__ == "__main__":
main()
说明
- 对应LeetCode第622题。
- 链接:https://leetcode-cn.com/problems/design-circular-queue/