本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
641. 设计循环双端队列
来源:力扣(LeetCode)
设计实现双端队列。
实现 MyCircularDeque 类:
MyCircularDeque(int k):构造函数,双端队列最大为 k 。boolean insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true ,否则返回 false 。boolean insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true ,否则返回 false 。boolean deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true ,否则返回 false 。boolean deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true ,否则返回 false 。int getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1 。int getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1 。boolean isEmpty():若双端队列为空,则返回 true ,否则返回 false 。boolean isFull():若双端队列满了,则返回 true ,否则返回 false 。
示例 1:
输入
["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
输出
[null, true, true, true, false, 2, true, true, true, 4]
解释
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
提示:
1 <= k <= 1000
0 <= value <= 1000
insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, isFull 调用次数不大于 2000 次
解法
- 列表实现:列表实现双端循环队列,加front表示起点,rear表示最后元素的下一个节点,用于判断是否满了
- 双链表:front和rear表示起始的头尾节点,无意义;
代码实现
列表实现
使用列表自带的性质; python实现
class MyCircularDeque:
def __init__(self, k: int):
self.deque = []
self.length = 0
self.max_length = k
def insertFront(self, value: int) -> bool:
if self.length < self.max_length:
self.deque = [value] + self.deque
self.length += 1
return True
return False
def insertLast(self, value: int) -> bool:
if self.length < self.max_length:
self.deque.append(value)
self.length += 1
return True
return False
def deleteFront(self) -> bool:
if self.length > 0:
self.deque.pop(0)
self.length -= 1
return True
return False
def deleteLast(self) -> bool:
if self.length > 0:
self.deque.pop()
self.length -= 1
return True
return False
def getFront(self) -> int:
return self.deque[0] if self.length > 0 else -1
def getRear(self) -> int:
return self.deque[-1] if self.length > 0 else -1
def isEmpty(self) -> bool:
return self.length == 0
def isFull(self) -> bool:
return self.length == self.max_length
# Your MyCircularDeque object will be instantiated and called as such:
# obj = MyCircularDeque(k)
# param_1 = obj.insertFront(value)
# param_2 = obj.insertLast(value)
# param_3 = obj.deleteFront()
# param_4 = obj.deleteLast()
# param_5 = obj.getFront()
# param_6 = obj.getRear()
# param_7 = obj.isEmpty()
# param_8 = obj.isFull()
使用front rear双指针,并将容量扩从为k+1
class MyCircularDeque:
def __init__(self, k: int):
self.deque = [0] * (k+1)
self.capacity = k+1
self.front = 0
self.rear = 0
def insertFront(self, value: int) -> bool:
if self.isFull():
return False
self.front -= 1
self.front += self.capacity
self.front %= self.capacity
self.deque[self.front] = value
return True
def insertLast(self, value: int) -> bool:
if self.isFull():
return False
self.deque[self.rear] = value
self.rear += 1
self.rear += self.capacity
self.rear %= self.capacity
return True
def deleteFront(self) -> bool:
if self.isEmpty():
return False
self.front += 1
self.front += self.capacity
self.front %= self.capacity
return True
def deleteLast(self) -> bool:
if self.isEmpty():
return False
self.rear -= 1
self.rear += self.capacity
self.rear %= self.capacity
return True
def getFront(self) -> int:
return self.deque[self.front] if not self.isEmpty() else -1
def getRear(self) -> int:
return self.deque[(self.rear-1+self.capacity)%self.capacity] if not self.isEmpty() else -1
def isEmpty(self) -> bool:
return self.front == self.rear
def isFull(self) -> bool:
return (self.rear+1) % self.capacity == self.front
# Your MyCircularDeque object will be instantiated and called as such:
# obj = MyCircularDeque(k)
# param_1 = obj.insertFront(value)
# param_2 = obj.insertLast(value)
# param_3 = obj.deleteFront()
# param_4 = obj.deleteLast()
# param_5 = obj.getFront()
# param_6 = obj.getRear()
# param_7 = obj.isEmpty()
# param_8 = obj.isFull()
c++实现
class MyCircularDeque {
private:
int front = 0;
int rear = 0;
int capacity = 0;
vector<int> deque;
// 用整型front作为数组的下标,指向队列的前端;用整型rear作为数组的下标,指向队列的尾部+1的位置,即下一个插入的位置
public:
MyCircularDeque(int k) {
capacity = k+1;
deque = vector<int>(k+1, 0);
}
bool insertFront(int value) {
if (isFull()) return false;
front--;
front += capacity;
front %= capacity;
deque[front] = value;
return true;
}
bool insertLast(int value) {
if (isFull())
return false;
deque[rear] = value;
rear++;
rear %= capacity;
return true;
}
bool deleteFront() {
if (isEmpty())
return false;
front++;
front %= capacity;
return true;
}
bool deleteLast() {
if (isEmpty())
return false;
rear--;
rear += capacity;
rear %= capacity;
return true;
}
int getFront() {
if (isEmpty())
return -1;
return deque[front];
}
int getRear() {
if (isEmpty())
return -1;
return deque[(rear-1+capacity)%capacity];
}
bool isEmpty() {
return front == rear;
}
bool isFull() {
return (rear+1) % capacity == front;
}
};
/**
* Your MyCircularDeque object will be instantiated and called as such:
* MyCircularDeque* obj = new MyCircularDeque(k);
* bool param_1 = obj->insertFront(value);
* bool param_2 = obj->insertLast(value);
* bool param_3 = obj->deleteFront();
* bool param_4 = obj->deleteLast();
* int param_5 = obj->getFront();
* int param_6 = obj->getRear();
* bool param_7 = obj->isEmpty();
* bool param_8 = obj->isFull();
*/
复杂度分析
- 时间复杂度:
- 空间复杂度:
双链表
python实现
class Node:
def __init__(self, val=-1, prev_node=None, next_node=None):
self.val = val
self.prev = prev_node
self.next = next_node
class MyCircularDeque(Node):
def __init__(self, k: int):
self.size = 0
self.capacity = k
self.front = Node(-1)
self.rear = Node(-1)
self.front.next = self.rear
self.rear.prev = self.front # 双链表
def insertFront(self, value: int) -> bool:
if self.isFull():
return False
v_node = Node(value)
next_node = self.front.next
self.front.next = v_node
v_node.next = next_node
v_node.prev = self.front
next_node.prev = v_node
self.size += 1
return True
def insertLast(self, value: int) -> bool:
if self.isFull():
return False
v_node = Node(value)
prev_node = self.rear.prev
v_node.prev = prev_node
prev_node.next = v_node
v_node.next = self.rear
self.rear.prev = v_node
self.size += 1
return True
def deleteFront(self) -> bool:
if self.isEmpty():
return False
v_node = self.front.next
self.front.next = v_node.next
self.front.next.prev = self.front
self.size -= 1
return True
def deleteLast(self) -> bool:
if self.isEmpty():
return False
v_node = self.rear.prev
self.rear.prev = v_node.prev
self.rear.prev.next = self.rear
self.size -= 1
return True
def getFront(self) -> int:
return self.front.next.val
def getRear(self) -> int:
return self.rear.prev.val
def isEmpty(self) -> bool:
return self.size == 0
def isFull(self) -> bool:
return self.size == self.capacity
# Your MyCircularDeque object will be instantiated and called as such:
# obj = MyCircularDeque(k)
# param_1 = obj.insertFront(value)
# param_2 = obj.insertLast(value)
# param_3 = obj.deleteFront()
# param_4 = obj.deleteLast()
# param_5 = obj.getFront()
# param_6 = obj.getRear()
# param_7 = obj.isEmpty()
# param_8 = obj.isFull()
c++实现
class Node {
public:
Node* next;
Node* prev;
int val;
Node(int val) {
this->val = val;
}
};
class MyCircularDeque {
public:
int capacity = 0;
int size = 0;
Node* front = new Node(-1);
Node* rear = new Node(-1);
MyCircularDeque(int k) {
capacity = k;
front->next = rear;
rear->prev = front;
}
bool insertFront(int value) {
if (isFull())
return false;
Node* n = new Node(value);
Node* next = front->next;
front->next = n;
n->next = next;
next->prev = n;
n->prev = front;
size++;
return true;
}
bool insertLast(int value) {
if (isFull())
return false;
Node* n = new Node(value);
Node* prev = rear->prev;
prev->next = n;
n->prev = prev;
n->next = rear;
rear->prev = n;
size++;
return true;
}
bool deleteFront() {
if (isEmpty())
return false;
Node* next = front->next;
front->next = next->next;
next->next->prev = front;
size--;
delete next;
return true;
}
bool deleteLast() {
if (isEmpty())
return false;
Node* prev = rear->prev;
rear->prev = prev->prev;
prev->prev->next = rear;
size--;
delete prev;
return true;
}
int getFront() {
return front->next->val;
}
int getRear() {
return rear->prev->val;
}
bool isEmpty() {
return size == 0;
}
bool isFull() {
return size == capacity;
}
};
/**
* Your MyCircularDeque object will be instantiated and called as such:
* MyCircularDeque* obj = new MyCircularDeque(k);
* bool param_1 = obj->insertFront(value);
* bool param_2 = obj->insertLast(value);
* bool param_3 = obj->deleteFront();
* bool param_4 = obj->deleteLast();
* int param_5 = obj->getFront();
* int param_6 = obj->getRear();
* bool param_7 = obj->isEmpty();
* bool param_8 = obj->isFull();
*/
复杂度分析
- 时间复杂度:
- 空间复杂度: