Stacks and queues — common interview applications
Stacks: LIFO — undo/redo, browser history, balanced parens, expression eval, DFS, monotonic stack (next-greater-element). Queues: FIFO — BFS, task scheduling, event loops, request batching, sliding-window-max via a deque. In JS both are arrays with push/pop or push/shift (or a deque-like structure).
Stacks and queues are the two simplest ordered containers and the building blocks of half the algorithms you'll see.
Stacks (LIFO)
A stack means "last in, first out." In JS: an array with push and pop — both O(1).
Frontend applications:
- Undo / redo — push every action onto an undo stack; pop on undo, push onto a redo stack.
- Browser history (back/forward).
- Call stack — recursion is itself stack-based.
- DFS — iterative DFS uses an explicit stack to avoid blowing the JS call stack.
- Balanced parentheses / bracket matching — push openers, pop and check on closers.
- Expression evaluation — shunting yard, postfix evaluation.
- Monotonic stack — next-greater-element, largest rectangle in histogram, daily temperatures.
function nextGreater(arr) {
const res = new Array(arr.length).fill(-1);
const stack = []; // indices, decreasing values
for (let i = 0; i < arr.length; i++) {
while (stack.length && arr[stack.at(-1)] < arr[i]) {
res[stack.pop()] = arr[i];
}
stack.push(i);
}
return res;
}Queues (FIFO)
"First in, first out." In JS: an array with push + shift — but shift is O(n). For real work use a linked-list-backed queue or a two-stack queue, or an index-based circular buffer.
Frontend applications:
- BFS — level-order traversal.
- Event loop / task queue — macrotask and microtask queues.
- Request queue — limit concurrent network requests (semaphore pattern).
- Animation/render queues — batched updates.
Deques
Double-ended queues underpin sliding-window-maximum (monotonic deque): O(n) instead of O(n·k).
Interview framing
"Stacks underlie undo/redo, browser history, iterative DFS, and the 'monotonic stack' pattern for next-greater-element problems. Queues underlie BFS, the event loop, and request batching. The JS gotcha is that array.shift() is O(n) — for hot queues I'd use a linked list or two-stack queue."
Follow-up questions
- •Implement a queue with two stacks.
- •How does undo/redo work with two stacks?
- •What is a monotonic stack and when does it help?
Common mistakes
- •Using array.shift() in hot loops — O(n) per op.
- •Forgetting to clear the redo stack on a new action.
- •Confusing stack and queue order in BFS/DFS.
Performance considerations
- •Stack push/pop O(1). Queue: push O(1), shift O(n) in plain arrays → use a linked-list / two-stack queue for O(1) amortized.
Edge cases
- •Empty pop/dequeue.
- •Mixed undo/redo with branching history.
- •Very deep recursion — switch DFS to iterative stack.
Real-world examples
- •Text editor undo/redo, browser history.
- •BFS in a graph / level-order tree render.
- •Request concurrency limiter with a queue of pending requests.