携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
一、题目
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 <= k <= 1000
0 <= value <= 1000
insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, isFull 调用次数不大于 2000 次
二、题解
根据题目要求设计一个循环双端队列,并且完成实现类中相对应的方法。
方法一
可以使用数组来模拟队列实现循环双端队列,具体的需要的类属性:
elements整形数组,当成队列使用,存储队列的元素;size队列大小,表示队列的元素最大值;head头部指针,指向队列的头部元素;tail尾部指针,指向队列的尾部元素。
然后对应的实现具体的方法,
MyCircularDeque(int k)方法构造函数,构造队列大小,首先初始化elements数组大小为k + 1,然后对应的size也为k + 1,最后初始的两个指针指向0位置;insertFront(int value)方法将元素添加到队列头部,首先判断如果队列已满则返回false,否则获取队列头部位置(head - 1 + size) % size,并且更新elements数组中头部位置head的值为value;insertLast(int value)方法将元素添加到队列尾部,首先判断如果队列已满则返回false,否则更新elements数组中尾部位置tail的值为value,并且获取尾部位置(tail + 1) % size;deleteFront()方法删除队列头部的一个元素,首先判断如果队列元素为空则返回false,否则直接更新head指针位置(head + 1) % size;deleteLast()方法删除队列尾部的一个元素,首先判断如果队列元素为空则返回false,否则直接更新tail指针位置(tail - 1 + size) % size;getFront()方法获取一个队列头部元素,首先判断如果队列为空的话则返回-1,否则返回elements数组中对应的头部位置元素;getRear()方法获取一个队列尾部元素,首先判断如果队列为空的话则返回-1,否则返回elements数组中对应尾部位置的元素;isEmpty()方法判断队列是否为空,判断两个指针head和tail位置是否相同,相同的则为空;isFull()方法判断队列元素是否已满,判断两个指针(tail + 1) % size == head相等的就是已满。
三、代码
方法一 Java代码
class MyCircularDeque {
private int[] elements;
private int head;
private int tail;
private int size;
public MyCircularDeque(int k) {
size = k + 1;
tail = head = 0;
elements = new int[k + 1];
}
public boolean insertFront(int value) {
if (isFull()) {
return false;
}
head = (head - 1 + size) % size;
elements[head] = value;
return true;
}
public boolean insertLast(int value) {
if (isFull()) {
return false;
}
elements[tail] = value;
tail = (tail + 1) % size;
return true;
}
public boolean deleteFront() {
if (isEmpty()) {
return false;
}
head = (head + 1) % size;
return true;
}
public boolean deleteLast() {
if (isEmpty()) {
return false;
}
tail = (tail - 1 + size) % size;
return true;
}
public int getFront() {
if (isEmpty()) {
return -1;
}
return elements[head];
}
public int getRear() {
if (isEmpty()) {
return -1;
}
return elements[(tail - 1 + size) % size];
}
public boolean isEmpty() {
return head == tail;
}
public boolean isFull() {
return head == (tail + 1) % size;
}
}
时间复杂度: O(1),只需常数的操作时间。
空间复杂度: O(n),需要使用的数组当成队列模拟。