携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
刷题的日常-2022年8月15日
一天一题,保持脑子清爽
设计循环双端队列
来自leetcode的 641 题,题意如下:
设计实现双端队列。
实现 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 。
理解题意
我们可以从题意中提取的条件如下:
- 要求我们设计一个双端队列
- 要求大小为k
- 然后要我们实现该队列的所有方法
做题思路
我们可以使用数组来实现该队列,维护两个指针,头指针和尾指针。头指针指向第一个元素,尾指针指向下一个写入的元素。队列是空的时候头指针和尾指针是相同的。队列满的时候,尾指针 + 1就等于头指针。边界问题我们可以多开辟一个空间来进行存储,可以少了很多判断。指针位移的过程中需要对长度进行取模,不然会出现索引越界。
代码实现
代码实现如下:
public class MyCircularDeque {
int[] queue;
int front, rear, len;
public MyCircularDeque(int k) {
queue = new int[len = (k + 1)];
front = rear = 0;
}
public boolean insertFront(int value) {
if (((rear + 1) % len) == front) {
return false;
}
front = (front + len - 1) % len;
queue[front] = value;
return true;
}
public boolean insertLast(int value) {
if (((rear + 1) % len) == front) {
return false;
}
queue[rear] = value;
rear = (rear + 1) % len;
return true;
}
public boolean deleteFront() {
if (front == rear) {
return false;
}
front = (front + 1) % len;
return true;
}
public boolean deleteLast() {
if (front == rear) {
return false;
}
rear = (rear + len - 1) % len;
return true;
}
public int getFront() {
if (front == rear) {
return -1;
}
return queue[front];
}
public int getRear() {
if (front == rear) {
return -1;
}
return queue[(rear + len - 1) % len];
}
public boolean isEmpty() {
return front == rear;
}
public boolean isFull() {
return (rear + 1) % len == front;
}
}