Try   HackMD

622. Design Circular Queue


My Solution

The Key Idea for Solving This Coding Question

用一個陣列來實作環狀佇列 (circular queue) 。不過,為了區分佇列為滿與佇列為空這兩種狀態,必須犧牲陣列中的一個元素不能存放資料。所以我們的陣列的長度必須是 k + 1
我們必須用兩個索引 (index) 來操作這個陣列。這兩個索引分別命名為 frontrearfront 指向佇列的第一個元素rear 指向佇列最後一個元素的下一個元素。所以, rear 所指向的那個元素永遠沒有資料。這就是為什麼我們的陣列長度必須是 k + 1 的原因。
另外,實作 Rear() 時,對陣列的操作必須注意。當 rear 指向索引值 0 時,佇列尾端的元素位於陣列的索引值 k 的位置。不能只是單純的用 rear - 1 去操作陣列。否則,會得到一個負的索引值去操作陣列,這樣是會有 runtime error 出現的。

C++ Code

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