Engineered
Data Structures

Design Circular Queue

Implement a fixed-capacity queue with circular array indices.

Try It Yourself

Use the editor below to process circular-queue operations without shifting values. Track the front position and current size inside a fixed-capacity array.

Submit your implementation when it passes the examples. Handle empty, full, capacity-one, and wraparound states.

Design Circular Queue

mediumQueue · Circular Buffer · Design35 minLC 622
Problem

Process operations on a fixed-capacity circular queue without shifting existing items.

Return one output per operation. The constructor produces null; enqueue and dequeue return booleans; Front, Rear, isEmpty, and isFull return their values.

Example 1:

Input: operations = ["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"], values = [[3], [1], [2], [3], [4], [], [], [], [4], []]
Output: [null, true, true, true, false, 3, true, true, true, 4]

Example 2:

Input: operations = ["MyCircularQueue", "Front", "Rear", "isEmpty"], values = [[2], [], [], []]
Output: [null, -1, -1, true]

Constraints

  • 1 ≤ capacity ≤ 1,000
  • At most 3,000 operations are performed.
0 attempts

Solution

The front index identifies the next value to remove. The insertion index is calculated from front plus size, wrapped by the capacity.

Dequeue advances front with the same wraparound calculation. Size distinguishes empty from full even when the indices occupy the same position.

function runCircularQueue(operations, values) {
  class MyCircularQueue {
    constructor(capacity) {
      this.items = Array(capacity);
      this.capacity = capacity;
      this.frontIndex = 0;
      this.size = 0;
    }

    enQueue(value) {
      if (this.isFull()) return false;
      const rearIndex = (this.frontIndex + this.size) % this.capacity;
      this.items[rearIndex] = value;
      this.size++;
      return true;
    }

    deQueue() {
      if (this.isEmpty()) return false;
      this.frontIndex = (this.frontIndex + 1) % this.capacity;
      this.size--;
      return true;
    }

    Front() {
      return this.isEmpty() ? -1 : this.items[this.frontIndex];
    }

    Rear() {
      if (this.isEmpty()) return -1;
      const rearIndex =
        (this.frontIndex + this.size - 1) % this.capacity;
      return this.items[rearIndex];
    }

    isEmpty() {
      return this.size === 0;
    }

    isFull() {
      return this.size === this.capacity;
    }
  }

  let queue;
  const output = [];

  for (let index = 0; index < operations.length; index++) {
    const operation = operations[index];

    if (operation === "MyCircularQueue") {
      queue = new MyCircularQueue(values[index][0]);
      output.push(null);
    } else if (operation === "enQueue") {
      output.push(queue.enQueue(values[index][0]));
    } else {
      output.push(queue[operation]());
    }
  }

  return output;
}

Big O notation

MeasureComplexityExplanation
TimeO(n)The wrapper performs n constant-time circular-queue operations.
Auxiliary spaceO(k)The fixed array stores exactly the queue capacity k.

How is this lesson?