题目
设计实现双端队列。你的实现需要支持以下操作:
- MyCircularDeque(k):构造函数,双端队列的大小为k。
- insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
- insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
- deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
- deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
- getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
- getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
- isEmpty():检查双端队列是否为空。
- isFull():检查双端队列是否满了。
示例如下:
- MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
- circularDeque.insertLast(1); // 返回 true
- circularDeque.insertLast(2); // 返回 true
- circularDeque.insertFront(3); // 返回 true
- circularDeque.insertFront(4); // 已经满了,返回 false
- circularDeque.getRear(); // 返回 2
- circularDeque.isFull(); // 返回 true
- circularDeque.deleteLast(); // 返回 true
- circularDeque.insertFront(4); // 返回 true
- circularDeque.getFront(); // 返回 4
解决思路
- 双端队列特点:队列的头部和尾部都能入队和出队(单端队列只能从头部出队尾部入队,即FIFO)。
- 使用数组实现队列的功能。解决思路与单端循环队列相同,见此博文:参考这里
代码
- C++代码
# include <stdio.h>
# include <vector>
using namespace std;
class MyCircularDeque {
public:
vector<int> arr; // 使用数组实现队列
int head; // 第一个元素的索引
int tail; // 最后一个元素的下一个位置的索引
int cnt; // 记录队列中元素的个数
MyCircularDeque(int k): arr(k), head(0), tail(0), cnt(0) {}
// 从对头插入元素
bool insertFront(int value) {
if (isFull()) {
return false;
}
head = (head - 1 + arr.size()) % arr.size(); // head要先向后退一步,再赋值
arr[head] = value;
cnt += 1;
return true;
}
// 从队尾插入元素
bool insertLast(int value) {
if (isFull()) {
return false;
}
arr[tail] = value;
tail = (tail + 1) % arr.size(); // 先赋值再将tail前进一步
cnt += 1;
return true;
}
// 从对头删除元素
bool deleteFront() {
if (isEmpty()) {
return false;
}
head = (head + 1) % arr.size();
cnt -= 1;
return true;
}
// 从队尾删除元素
bool deleteLast() {
if (isEmpty()) {
return false;
}
tail = (tail - 1 + arr.size()) % arr.size();
cnt -= 1;
return true;
}
// 获取对头元素
int getFront() {
if (isEmpty()) {
return -1;
}
return arr[head];
}
// 获取队尾元素
int getRear() {
if (isEmpty()) {
return -1;
}
return arr[(tail - 1 + arr.size()) % arr.size()];
}
// 判断队列是否为空
bool isEmpty() {
return 0 == cnt;
}
// 判断队列是否已满
bool isFull() {
return arr.size() == cnt;
}
};
int main() {
int k = 3; // 设置容量大小为3
MyCircularDeque *circularDeque = new MyCircularDeque(k);
printf("%d\n", circularDeque->insertLast(1)); // 返回 true
printf("%d\n", circularDeque->insertLast(2)); // 返回 true
printf("%d\n", circularDeque->insertFront(3)); // 返回 true
printf("%d\n", circularDeque->insertFront(4)); // 已经满了,返回 false
printf("%d\n", circularDeque->getRear());
printf("%d\n", circularDeque->isFull());
printf("%d\n", circularDeque->deleteLast());
printf("%d\n", circularDeque->insertFront(4));
printf("%d\n", circularDeque->getFront());
return 0;
}
- python代码
# -*- coding: utf-8 -*-
class MyCircularDeque:
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 insertFront(self, value: int):
if self.isFull():
return False
self.head = (self.head - 1 + self.size) % self.size # head要先向后退一步,再赋值
self.arr[self.head] = value
self.cnt += 1
return True
# 从队尾插入元素
def insertLast(self, value: int):
if self.isFull():
return False
self.arr[self.tail] = value
self.tail = (self.tail + 1) % self.size # 先赋值再将tail前进一步
self.cnt += 1
return True
# 从对头删除元素
def deleteFront(self):
if self.isEmpty():
return False
self.head = (self.head + 1) % self.size
self.cnt -= 1
return True
# 从队尾删除元素
def deleteLast(self):
if self.isEmpty():
return False
self.tail = (self.tail - 1 + self.size) % self.size
self.cnt -= 1
return True
# 获取对头元素
def getFront(self):
if self.isEmpty():
return -1;
return self.arr[self.head]
# 获取队尾元素
def getRear(self):
if self.isEmpty():
return -1
return self.arr[(self.tail - 1 + self.size) % self.size]
# 判断队列是否为空
def isEmpty(self):
return 0 == self.cnt
# 判断队列是否已满
def isFull(self):
return self.size == self.cnt
def main():
k: int = 3
circularDeque: MyCircularDeque = MyCircularDeque(k)
print(circularDeque.insertLast(1))
print(circularDeque.insertLast(2))
print(circularDeque.insertFront(3))
print(circularDeque.insertFront(4))
print(circularDeque.getRear())
print(circularDeque.isFull())
print(circularDeque.deleteLast())
print(circularDeque.insertFront(4))
print(circularDeque.getFront())
if __name__ == "__main__":
main()
说明
- 对应LeetCode第641题。
- 链接:https://leetcode-cn.com/problems/design-circular-deque/