--- 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],[],[],[],[],[]] ``` -->