{
  "id": "stacks-queues/deque",
  "version": 1,
  "deterministic": true,
  "url": "/dsa/stacks-queues/deque",
  "topic": {
    "slug": "stacks-queues",
    "title": "Stacks & Queues"
  },
  "title": "Deque",
  "tagline": "A queue open at both ends — a stack and a queue in one structure.",
  "vizKind": "queue",
  "complexity": {
    "time": {
      "best": "O(1)",
      "average": "O(1)",
      "worst": "O(1)"
    },
    "space": "O(n)",
    "growth": "constant",
    "note": "All four operations — push and pop at either end — are O(1), because nothing ever shuffles. Built on a doubly linked list or a circular buffer; never on a plain array, where pushFront would be O(n)."
  },
  "code": {
    "javascript": "class Deque {\n  constructor() { this.items = []; }\n  pushFront(v) { this.items.unshift(v); }\n  pushBack(v)  { this.items.push(v); }\n  popFront()   { return this.items.shift(); }\n  popBack()    { return this.items.pop(); }\n  peekFront()  { return this.items[0]; }\n  peekBack()   { return this.items[this.items.length - 1]; }\n  isEmpty()    { return this.items.length === 0; }\n}",
    "python": "from collections import deque\n\nclass Deque:\n    def __init__(self): self.items = deque()\n    def push_front(self, v): self.items.appendleft(v)\n    def push_back(self, v):  self.items.append(v)\n    def pop_front(self):     return self.items.popleft()\n    def pop_back(self):      return self.items.pop()\n    def peek_front(self):    return self.items[0]\n    def peek_back(self):     return self.items[-1]\n    def is_empty(self):      return len(self.items) == 0\n",
    "java": "class Deque {\n  private ArrayDeque<Integer> items = new ArrayDeque<>();\n  void pushFront(int v) { items.addFirst(v); }\n  void pushBack(int v)  { items.addLast(v); }\n  Integer popFront()    { return items.pollFirst(); }\n  Integer popBack()     { return items.pollLast(); }\n  Integer peekFront()   { return items.peekFirst(); }\n  Integer peekBack()    { return items.peekLast(); }\n  boolean isEmpty()     { return items.isEmpty(); }\n}",
    "cpp": "class Deque {\n  deque<int> items;\npublic:\n  void pushFront(int v) { items.push_front(v); }\n  void pushBack(int v)  { items.push_back(v); }\n  int  popFront()  { int v = items.front(); items.pop_front(); return v; }\n  int  popBack()   { int v = items.back();  items.pop_back();  return v; }\n  int  peekFront() { return items.front(); }\n  int  peekBack()  { return items.back(); }\n  bool isEmpty()   { return items.empty(); }\n};"
  },
  "defaultInput": [
    3,
    7,
    1,
    9,
    5
  ],
  "defaultTarget": null,
  "inputHint": "These get added alternately at the front and back. Then both ends are popped.",
  "pitfalls": [
    {
      "wrong": "Building a deque on a plain array and using unshift() for pushFront.",
      "right": "unshift shifts every element right — O(n). Use a real deque (a circular buffer or doubly linked list) where both ends are just pointers."
    },
    {
      "wrong": "Reaching into the middle of a deque.",
      "right": "You can't, and that's deliberate. If you need the middle, you want an array. The restriction is what buys the O(1)."
    },
    {
      "wrong": "Not realising you already have one.",
      "right": "Python's collections.deque, Java's ArrayDeque, C++'s std::deque. Don't hand-roll it — and note that Java's ArrayDeque is the recommended stack *and* queue implementation."
    }
  ],
  "quiz": [
    {
      "q": "What makes a deque different from a queue?",
      "options": [
        "It's faster",
        "You can add and remove at both ends, not just one each",
        "It sorts its contents",
        "It has unlimited size"
      ],
      "answer": 1,
      "why": "A queue adds at the back and removes from the front. A deque lets you do either operation at either end — which is why it can act as a stack *or* a queue."
    },
    {
      "q": "Use only pushBack and popBack on a deque. What have you built?",
      "options": [
        "A queue",
        "A stack",
        "A heap",
        "A linked list"
      ],
      "answer": 1,
      "why": "Adding and removing at the same end is last-in-first-out — that's a stack, exactly. A deque contains both structures inside it."
    },
    {
      "q": "Why is pushFront on a plain JavaScript array slow?",
      "options": [
        "Arrays can't grow",
        "unshift() shifts every existing element right one place — O(n)",
        "It's not slow",
        "Because of garbage collection"
      ],
      "answer": 1,
      "why": "Same cost you met in the Arrays lesson: inserting at the front makes everything else shuffle. A true deque keeps a pointer to each end, so neither end costs anything."
    }
  ],
  "problems": [
    {
      "name": "Sliding Window Maximum",
      "difficulty": "Hard",
      "url": "https://leetcode.com/problems/sliding-window-maximum/"
    },
    {
      "name": "Design Front Middle Back Queue",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/design-front-middle-back-queue/"
    },
    {
      "name": "Number of Recent Calls",
      "difficulty": "Easy",
      "url": "https://leetcode.com/problems/number-of-recent-calls/"
    }
  ],
  "trace": {
    "note": "Each frame is one immutable step: data snapshot, pointers, per-index roles, executing code line, and a one-sentence explanation.",
    "length": 9,
    "frames": [
      {
        "data": {
          "items": []
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 1,
        "variables": {
          "size": 0
        },
        "explanation": "A deque — 'deck' — is a queue that opens at both ends. You can add or remove at the front or the back, whichever suits you.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d0-3",
              "value": 3
            }
          ]
        },
        "pointers": [
          {
            "name": "front",
            "index": 0
          },
          {
            "name": "back",
            "index": 0
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "swap"
          }
        ],
        "codeLine": 3,
        "variables": {
          "added": 3,
          "at": "front",
          "size": 1
        },
        "explanation": "pushFront(3) — 3 jumps straight to the front of the line. A plain queue would never let you do that.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            }
          ]
        },
        "pointers": [
          {
            "name": "front",
            "index": 0
          },
          {
            "name": "back",
            "index": 1
          }
        ],
        "highlights": [
          {
            "index": 1,
            "role": "swap"
          }
        ],
        "codeLine": 4,
        "variables": {
          "added": 7,
          "at": "back",
          "size": 2
        },
        "explanation": "pushBack(7) — 7 joins the back, exactly like an ordinary queue.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            }
          ]
        },
        "pointers": [
          {
            "name": "front",
            "index": 0
          },
          {
            "name": "back",
            "index": 2
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "swap"
          }
        ],
        "codeLine": 3,
        "variables": {
          "added": 1,
          "at": "front",
          "size": 3
        },
        "explanation": "pushFront(1) — 1 jumps straight to the front of the line. A plain queue would never let you do that.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            },
            {
              "id": "d3-9",
              "value": 9
            }
          ]
        },
        "pointers": [
          {
            "name": "front",
            "index": 0
          },
          {
            "name": "back",
            "index": 3
          }
        ],
        "highlights": [
          {
            "index": 3,
            "role": "swap"
          }
        ],
        "codeLine": 4,
        "variables": {
          "added": 9,
          "at": "back",
          "size": 4
        },
        "explanation": "pushBack(9) — 9 joins the back, exactly like an ordinary queue.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d4-5",
              "value": 5
            },
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            },
            {
              "id": "d3-9",
              "value": 9
            }
          ]
        },
        "pointers": [
          {
            "name": "front",
            "index": 0
          },
          {
            "name": "back",
            "index": 4
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "swap"
          }
        ],
        "codeLine": 3,
        "variables": {
          "added": 5,
          "at": "front",
          "size": 5
        },
        "explanation": "pushFront(5) — 5 jumps straight to the front of the line. A plain queue would never let you do that.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            },
            {
              "id": "d3-9",
              "value": 9
            }
          ]
        },
        "pointers": [],
        "highlights": [
          {
            "index": 0,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "removed": 5,
          "from": "front",
          "size": 4
        },
        "explanation": "popFront() — take 5 off the front. Do only this and pushBack, and you have built a queue.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            }
          ]
        },
        "pointers": [],
        "highlights": [
          {
            "index": 2,
            "role": "active"
          }
        ],
        "codeLine": 6,
        "variables": {
          "removed": 9,
          "from": "back",
          "size": 3
        },
        "explanation": "popBack() — take 9 off the back. Do only this and pushBack, and you have built a stack.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": {
          "items": [
            {
              "id": "d2-1",
              "value": 1
            },
            {
              "id": "d0-3",
              "value": 3
            },
            {
              "id": "d1-7",
              "value": 7
            }
          ]
        },
        "pointers": [],
        "highlights": [],
        "codeLine": 9,
        "variables": {
          "size": 3
        },
        "explanation": "3 left. Every one of those four operations was O(1) — a deque never shuffles anything, because it only ever touches an end. It is the structure behind sliding-window maximums and browser history.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      }
    ]
  }
}