The Indian Engineer

Problem 641 Design Circular Deque

Posted on 7 mins

Array Linked-List Design Queue

Problem Statement

Link - Problem 641

Question

Design your implementation of the circular double-ended queue (deque).

Implement the MyCircularDeque class:

Example 1:

Input
["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 2, true, true, true, 4]

Explanation
MyCircularDeque myCircularDeque = new MyCircularDeque(3);
myCircularDeque.insertLast(1);  // return True
myCircularDeque.insertLast(2);  // return True
myCircularDeque.insertFront(3); // return True
myCircularDeque.insertFront(4); // return False, the queue is full.
myCircularDeque.getRear();      // return 2
myCircularDeque.isFull();       // return True
myCircularDeque.deleteLast();   // return True
myCircularDeque.insertFront(4); // return True
myCircularDeque.getFront();     // return 4

Constraints:

Solution

class MyCircularDeque {
private:
    vector<int>arr;
    int front;
    int rear;
    int capacity;
    int size;

public:
    MyCircularDeque(int k) {
        capacity = k;
        arr.resize(capacity);
        front = 0;
        rear = 0;
        size = 0;
    }

    bool insertFront(int value) {
        if (isFull())
            return false;
        front = (front - 1 + capacity) % capacity;
        arr[front] = value;
        size++;
        return true;
    }

    bool insertLast(int value) {
        if (isFull())
            return false;
        arr[rear] = value;
        rear = (rear + 1) % capacity;
        size++;
        return true;
    }

    bool deleteFront() {
        if (isEmpty())
            return false;
        front = (front + 1) % capacity;
        size--;
        return true;
    }

    bool deleteLast() {
        if (isEmpty())
            return false;
        rear = (rear - 1 + capacity) % capacity;
        size--;
        return true;
    }

    int getFront() {
        if (isEmpty())
            return -1;
        return arr[front];
    }

    int getRear() {
        if (isEmpty())
            return -1;
        return arr[(rear - 1 + capacity) % capacity];
    }

    bool isEmpty() {
        return size == 0;
    }

    bool isFull() {
        return size == capacity;
    }

};

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */

Complexity Analysis

| Algorithm                     | Time Complexity | Space Complexity |
| ----------------------------- | --------------- | ---------------- |
| Circular Array Implementation | O(1)            | O(k)             |

Explanation

Intial Thoughts

To approach this problem, consider a circular buffer where elements can be added or removed from both ends. Think of it as a merry-go-round where you can get on or off at either end. Start by initializing the deque with a maximum size, and keep track of the front and rear pointers. Consider how to handle cases where the deque is full or empty. Think about how to update the front and rear pointers when elements are added or removed.

Intuitive Analysis

Intuitively, solving this problem involves understanding how a circular deque works. Imagine a ring where you can insert or delete elements at any point. To insert an element at the front, move the front pointer backwards and add the element. To insert at the rear, move the rear pointer forwards and add the element. When deleting, move the corresponding pointer in the opposite direction. Keep track of the size of the deque to handle full or empty cases. Visualize the process like a circular train where cars can be added or removed at either end, and the train can wrap around itself.

1. Intuition

2. Implementation


Complexity Analysis

Time Complexity:

Space Complexity:


Footnote

This question is rated as Medium difficulty.


Similar Questions:

Title URL Difficulty
Design Circular Queue https://leetcode.com/problems/design-circular-queue Medium
Design Front Middle Back Queue https://leetcode.com/problems/design-front-middle-back-queue Medium