解析:
- 每种方法都需要设置代表首、尾的变量,设为front、rear。
- 在rear位置插入即入队列,front位置删除即出队列。
- 循环队列找到首尾的算法都是 (rear或front + 1) % length。
C++
class MyCircularQueue {
public:
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) {
data.resize(k);
head = 0;
tail = 0;
reset = true;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
bool enQueue(int value) {
if (isFull()) return false;
// update the reset value when first enqueue happens
if (head == tail && reset) reset = false;
data[tail] = value;
tail = (tail + 1) % data.size();
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
bool deQueue() {
if (isEmpty()) return false;
head = (head + 1) % data.size();
// update the reset value when last dequeue happens
if (head == tail && !reset) reset = true;
return true;
}
/** Get the front item from the queue. */
int Front() {
if (isEmpty()) return -1;
return data[head];
}
/** Get the last item from the queue. */
int Rear() {
if (isEmpty()) return -1;
return data[(tail + data.size() - 1) % data.size()];
}
/** Checks whether the circular queue is empty or not. */
bool isEmpty() {
if (tail == head && reset) return true;
return false;
}
/** Checks whether the circular queue is full or not. */
bool isFull() {
if (tail == head && !reset) return true;
return false;
}
private:
vector<int> data;
int head;
int tail;
// reset is the mark when the queue is empty
// to differentiate from queue is full
// because in both conditions (tail == head) stands
bool reset;
};
/**
* Your MyCircularQueue object will be instantiated and called as such:
* MyCircularQueue obj = new MyCircularQueue(k);
* bool param_1 = obj.enQueue(value);
* bool param_2 = obj.deQueue();
* int param_3 = obj.Front();
* int param_4 = obj.Rear();
* bool param_5 = obj.isEmpty();
* bool param_6 = obj.isFull();
*/
存储结构: vector<int>
设定判断初始状态标志reset(但其实可以不单独考虑第一次情况,见java版)
用tail == head && reset 判断空
用tail == head && !reset 判断满
改进C++版(空或满用当前长度替换,提高代码理解度)
python
class MyCircularQueue(object):
def __init__(self, k):
self.lst = [0] * k
self.size, self.k = 0, k
self.l = self.r = 0
def enQueue(self, value):
if not self.isFull():
self.lst[self.r] = value
self.r = (self.r+1) % self.k
self.size += 1
return True
return False
def deQueue(self):
if not self.isEmpty():
self.l = (self.l+1) % self.k
self.size -= 1
return True
return False
def Front(self):
return self.lst[self.l] if self.size else -1
def Rear(self):
# for this part, because it's python so 0-1 = -1 is also a valid indexing, so just "self.r-1" may also work, but I just want to be clearer.
return self.lst[(self.r+self.k-1)%self.k] if self.size else -1
def isEmpty(self):
return True if not self.size else False
def isFull(self):
return True if self.size == self.k else False
https://leetcode.com/explore/featured/card/queue-stack/228/first-in-first-out-data-structure/1337/discuss/213130/Python-fixed-length-k-array-2-pointers-solution-easy-and-short.
java
class MyCircularQueue {
final int[] a;
int front, rear = -1, len = 0;
public MyCircularQueue(int k) { a = new int[k];}
public boolean enQueue(int val) {
if (!isFull()) {
rear = (rear + 1) % a.length;
a[rear] = val;
len++;
return true;
} else return false;
}
public boolean deQueue() {
if (!isEmpty()) {
front = (front + 1) % a.length;
len--;
return true;
} else return false;
}
public int Front() { return isEmpty() ? -1 : a[front];}
public int Rear() {return isEmpty() ? -1 : a[rear];}
public boolean isEmpty() { return len == 0;}
public boolean isFull() { return len == a.length;}
}
存储结构:array
设置现长度变量 len,通过每次入队出队更新达到简便判断的效果