题目
算法思路
思路一
思路分析
源码
class MyCircularDeque {
//创建数组队列
private int[] elements;
//定义头指针
private int rear;
//定义尾指针
private int front;
//队列长度
private int capacity;
public MyCircularDeque(int k) {
capacity = k + 1;
rear = front = 0;
//可以创建k+1的数组,也可以创建k的数组
elements = new int[k + 1];
}
//将一个元素添加到双端队列头部
public boolean insertFront(int value) {
if (isFull()) {
//队列满了,插入不了,返回false
return false;
}
//头部索引的前一位为空,所以front向前一步
front = (front - 1 + capacity) % capacity;
//为空的位置添加元素
elements[front] = value;
return true;
}
//将一个元素添加到双端队列尾部
public boolean insertLast(int value) {
if (isFull()) {
//队列满了,插入不了,返回false
return false;
}
//此时rear指向尾部,直接添加
elements[rear] = value;
//同时更新尾部指针索引向后一步
rear = (rear + 1) % capacity;
return true;
}
//从双端队列头部删除一个元素
public boolean deleteFront() {
if (isEmpty()) {
//队列为空,删不了,返回false
return false;
}
//不为空,直接改变头部索引+1
front = (front + 1) % capacity;
return true;
}
//从双端队列尾部删除一个元素
public boolean deleteLast() {
if (isEmpty()) {
//队列为空,无法删除,返回false
return false;
}
//不为空,尾部索引向前一步
rear = (rear - 1 + capacity) % capacity;
return true;
}
//从双端队列头部获得一个元素
public int getFront() {
if (isEmpty()) {
//队列为空,返回-1
return -1;
}
return elements[front];
}
//获得双端队列的最后一个元素
public int getRear() {
if (isEmpty()) {
//队列为空,返回-1
return -1;
}
return elements[(rear - 1 + capacity) % capacity];
}
//若双端队列为空,则返回 true
public boolean isEmpty() {
//如果头尾指针相等就为空
return rear == front;
}
//若双端队列满了,则返回 true
public boolean isFull() {
return (rear + 1) % capacity == front;
}
}
/**
* Your MyCircularDeque object will be instantiated and called as such:
* MyCircularDeque obj = new MyCircularDeque(k);
* boolean param_1 = obj.insertFront(value);
* boolean param_2 = obj.insertLast(value);
* boolean param_3 = obj.deleteFront();
* boolean param_4 = obj.deleteLast();
* int param_5 = obj.getFront();
* int param_6 = obj.getRear();
* boolean param_7 = obj.isEmpty();
* boolean param_8 = obj.isFull();
*/
时间和空间复杂度
所用API
总结(循环双端队列)
1.循环对列
队列在数组前部删除元素后,如果后面的位置满了,就无法在添加值,但是在前面却还有空位,这时入队出现“上溢”,但这种溢出并不是真正的溢出,数组中仍存在可以放置元素的位置,所以为“假溢出”。为了解决此问题,就出现了循环队列。
循环队列就是将 队列 存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。. 在循环队列结构中,当存储空间的最后一个位置已被使用而再要进入队运算时,只需要存储空间的第一个位置空闲,便可将元素加入到第一个位置,即将存储空间的第一个位置作为队尾。 循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。 为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize。
2.循环双端队列
提示:实现可看题解代码:
循环双端队列在循环对列的基础上实现类头部和尾部可以同时实现添加和删除。
以下为所添加的位置计算公式
font为头指针,rear为尾指针,capacity队列长度
- 头部添加:(front - 1 + capacity) % capacity
- 头部删除:(front + 1) % capacity
- 尾部添加:(rear + 1) % capacity
- 尾部删除:(rear - 1 + capacity) % capacity