---
tags: leetcode
---
# [622. Design Circular Queue](https://leetcode.com/problems/design-circular-queue/)
---
# My Solution
## The Key Idea for Solving This Coding Question
用一個陣列來實作環狀佇列 (circular queue) 。不過,==為了區分佇列為滿與佇列為空這兩種狀態,必須犧牲陣列中的一個元素不能存放資料==。所以我們的陣列的長度必須是 `k + 1` 。
我們必須用兩個索引 (index) 來操作這個陣列。這兩個索引分別命名為 `front` 與 `rear` 。 ==`front` 指向佇列的第一個元素==, ==`rear` 指向佇列最後一個元素的下一個元素==。所以, ==`rear` 所指向的那個元素永遠沒有資料==。這就是為什麼我們的陣列長度必須是 `k + 1` 的原因。
另外,實作 `Rear()` 時,對陣列的操作必須注意。當 `rear` 指向索引值 `0` 時,佇列尾端的元素位於陣列的索引值 `k` 的位置。不能只是單純的用 `rear - 1` 去操作陣列。否則,會得到一個負的索引值去操作陣列,這樣是會有 runtime error 出現的。
## C++ Code
```cpp=
class MyCircularQueue {
public:
MyCircularQueue(int k) {
front = 0;
rear = 0;
qLen = k + 1;
q.resize(qLen);
}
bool enQueue(int value) {
if (isFull()) {
return false;
}
q[rear] = value;
rear = (rear + 1) % qLen;
return true;
}
bool deQueue() {
if (isEmpty()) {
return false;
}
front = (front + 1) % qLen;
return true;
}
int Front() {
if (isEmpty()) {
return -1;
}
return q[front];
}
int Rear() {
if (isEmpty()) {
return -1;
}
return q[(rear - 1 + qLen) % qLen];
}
bool isEmpty() {
return front == rear;
}
bool isFull() {
return (rear + 1) % qLen == front;
}
private:
int front;
int rear;
int qLen;
vector<int> q;
};
/**
* 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();
*/
```
## Time Complexity
* `MyCircularQueue`
$O(k)$
* `enQueue`
$O(1)$
* `deQueue`
$O(1)$
* `Front`
$O(1)$
* `Rear`
$O(1)$
* `isEmpty`
$O(1)$
* `isFull`
$O(1)$
## Space Complexity
* `MyCircularQueue`
$O(k)$
* `enQueue`
$O(1)$
* `deQueue`
$O(1)$
* `Front`
$O(1)$
* `Rear`
$O(1)$
* `isEmpty`
$O(1)$
* `isFull`
$O(1)$
# Miscellaneous
<!--
# Test Cases
```
["MyCircularQueue","enQueue","enQueue","enQueue","enQueue","Rear","isFull","deQueue","enQueue","Rear"]
[[3],[1],[2],[3],[4],[],[],[],[4],[]]
```
```
["MyCircularQueue","enQueue","Rear","Rear","deQueue","enQueue","Rear","deQueue","Front","deQueue","deQueue","deQueue"]
[[6],[6],[],[],[],[5],[],[],[],[],[],[]]
```
```
["MyCircularQueue","enQueue","enQueue","enQueue","enQueue","Rear","isFull","deQueue","enQueue","Rear","deQueue","deQueue","deQueue","isEmpty"]
[[3],[1],[2],[3],[4],[],[],[],[4],[],[],[],[],[]]
```
-->