「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
设计循环双端队列 Design Circular Deque
LeetCode传送门641. 设计循环双端队列
题目
设计实现双端队列。 你的实现需要支持以下操作:
-
MyCircularDeque(k):构造函数,双端队列的大小为k。
-
insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
-
insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
-
deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
-
deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
-
getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
-
getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
-
isEmpty():检查双端队列是否为空。
-
isFull():检查双端队列是否满了。
Design your implementation of the circular double-ended queue (deque).
Implement the MyCircularDeque class:
MyCircularDeque(int k)Initializes the deque with a maximum size ofk.- boolean
insertFront()Adds an item at the front of Deque. Returnstrueif the operation is successful, orfalseotherwise. - boolean
insertLast()Adds an item at the rear of Deque. Returnstrueif the operation is successful, orfalseotherwise. - boolean
deleteFront()Deletes an item from the front of Deque. Returnstrueif the operation is successful, orfalseotherwise. - boolean
deleteLast()Deletes an item from the rear of Deque. Returnstrueif the operation is successful, orfalseotherwise. - int
getFront()Returns the front item from the Deque. Returns-1if the deque is empty. - int
getRear()Returns the last item from Deque. Returns-1if the deque is empty. - boolean
isEmpty()Returnstrueif the deque is empty, orfalseotherwise. - boolean
isFull()Returnstrueif the deque is full, or false otherwise.
Example:
Input
["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 2, true, true, true, 4]
Explanation
MyCircularDeque myCircularDeque = new MyCircularDeque(3);
myCircularDeque.insertLast(1); // return True
myCircularDeque.insertLast(2); // return True
myCircularDeque.insertFront(3); // return True
myCircularDeque.insertFront(4); // return False, the queue is full.
myCircularDeque.getRear(); // return 2
myCircularDeque.isFull(); // return True
myCircularDeque.deleteLast(); // return True
myCircularDeque.insertFront(4); // return True
myCircularDeque.getFront(); // return 4
Constraints:
- 1 <= k <= 1000
- 0 <= value <= 1000
- At most 2000 calls will be made to
insertFront,insertLast,deleteFront,deleteLast,getFront,getRear,isEmpty,isFull.
思考线
解题思路
本题和上一道题循环队列基本相同,对于相同的内容,在这里不多赘述,不太明白的同学可以去看
// TODO Link
本题我们只专注于两个方法的分析insertFront和deleteLast.
我们首先来看deleteLast.这个比较简单,我们只需要在 size不为0时,执行size --即可。
最后我们再看一下insertFront.若元素没被排满的情况下,我们要如何放置这个新元素呢?
- 若此时的
head不为0我们只需要让head往前挪动一个位置即可,同时把该位置赋值,最后让size++ - 若
head ===0,我们只要把head挪到数组的最后一个位置len -1即可。
以上就是我们基于循环队列实现的双端循环队列。
代码如下:
class MyCircularDeque {
queue: number[]
head: number
size: number
len: number;
constructor(k: number) {
this.len = k;
this.queue = new Array(k);
this.size = 0;
this.head = 0;
}
insertFront(value: number): boolean {
if (this.isFull()) return false;
if (this.head === 0) {
this.head = this.len - 1;
this.queue[this.len - 1] = value;
} else {
this.queue[--this.head] = value;
}
this.size++;
return true;
}
insertLast(value: number): boolean {
if (this.isFull()) return false;
this.queue[(this.head + this.size + this.len) % this.len] = value;
this.size++;
return true;
}
deleteFront(): boolean {
if (this.isEmpty()) return false;
if (this.head === this.len - 1) {
this.head = 0
} else {
this.head++
};
this.size--;
return true;
}
deleteLast(): boolean {
if (this.isEmpty()) return false;
this.size--;
return true;
}
getFront(): number {
if (this.isEmpty()) {
return -1;
}
return this.queue[this.head];
}
getRear(): number {
if (this.isEmpty()) {
return -1;
}
return this.queue[(this.head + this.size - 1) % this.len];
}
isEmpty(): boolean {
return this.size === 0;
}
isFull(): boolean {
return this.size === this.len;
}
}
/**
* Your MyCircularDeque object will be instantiated and called as such:
* var obj = new MyCircularDeque(k)
* var param_1 = obj.insertFront(value)
* var param_2 = obj.insertLast(value)
* var param_3 = obj.deleteFront()
* var param_4 = obj.deleteLast()
* var param_5 = obj.getFront()
* var param_6 = obj.getRear()
* var param_7 = obj.isEmpty()
* var param_8 = obj.isFull()
*/
时间复杂度
O(1): 在上面的数据结构中,所有的方法都有恒定的时间复杂度。
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。