Stack: Code Templates in 6 Languages
If you have not read the concept guide yet, start there for the LIFO intuition and complexity analysis. This page gives you the code you can memorize and adapt during an interview. The main template is the stack container itself, and the variations cover the three shapes most interview problems take: bracket matching, expression evaluation, and tracking a running minimum. The monotonic stack, which answers next greater queries, has its own page because the ordering rules deserve the extra room.
Main Template: Stack Container
This is the base layer of every stack solution. Most languages ship a built-in stack and interviews accept it, but implementing the container once makes the interface and the empty checks automatic. The empty check matters more than push and pop, because reading from an empty stack is the most common stack bug.
Use this for Min Stack , which layers a second stack on top of this one.
class Stack {
constructor() {
this.items = [];
}
// The top is always the last index of the backing array,
// so push is just an append at the end.
push(item) {
this.items.push(item);
}
// Guard the pop before touching the array. Reading from
// an empty stack is the most common stack bug.
pop() {
if (this.isEmpty()) return null;
return this.items.pop();
}
peek() {
if (this.isEmpty()) return null;
return this.items[this.items.length - 1];
}
isEmpty() {
return this.items.length === 0;
}
}Code Breakdown
Key Variables
items(backing array): the stack itself. The top element is always the last index, which is what makes push and pop.O(1)isEmpty()(the guard): the check that must run before every pop and peek. It is the one line that separates correct stack code from a crash on the first edge case.
Visual Mechanism
graph LR
A[Start] --> B{Operation?}
B -->|Push| C[Append to the end]
B -->|Pop or Peek| D{Is the stack empty?}
D -->|Yes| E[Return null or raise]
D -->|No| F[Touch the last element]
C --> G[New state]
F --> G
Critical Sections
The initialization is just an empty array. No sentinel is needed because the empty check covers the base case.
The pop guard is the critical section. Check emptiness before removing, not after. When a problem uses the language’s built-in stack directly, the same guard applies: peek or pop only after confirming the stack is not empty.
The peek and pop distinction matters inside algorithms. Peek leaves the stack unchanged, so the next iteration still sees the same top. Pop changes the state. Code that pops when it only needed to look will silently skip an element on the next pass. When a solution behaves oddly and an element disappears, check whether peek was the right call.
Variations
1. Bracket Matching
Every opener must be closed by its matching closer in reverse order, so push openers and validate against the top when a closer arrives. Runs in
Use this for Valid Parentheses .
function isValid(s) {
const stack = [];
const matches = { ')': '(', '}': '{', ']': '[' };
for (const c of s) {
if (matches[c]) {
// A closer must match the most recent unclosed
// opener, which is the stack top.
if (stack.pop() !== matches[c]) return false;
} else {
stack.push(c);
}
}
// Openers left on the stack were never closed.
return stack.length === 0;
}2. Expression Evaluation (Reverse Polish Notation)
An operator applies to the most recent operands, so push numbers and pop the top two when an operator arrives. Runs in
Use this for Evaluate Reverse Polish Notation .
function evalRPN(tokens) {
const stack = [];
const ops = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
// Integer division must truncate toward zero,
// so Math.trunc beats Math.floor here.
'/': (a, b) => Math.trunc(a / b)
};
for (const token of tokens) {
if (ops[token]) {
// The first pop is the right operand because
// it sits above the left one on the stack.
const b = stack.pop();
const a = stack.pop();
stack.push(ops[token](a, b));
} else {
stack.push(Number(token));
}
}
return stack[0];
}3. Min Stack (Auxiliary Stack)
When the problem asks for a running property like the minimum alongside normal push and pop, keep a second stack that records only the values that change that property. Each operation stays
Use this for Min Stack .
class MinStack {
constructor() {
this.stack = [];
this.minStack = [];
}
push(val) {
this.stack.push(val);
// minStack only records new minimums, so its top is
// always the minimum of the whole stack.
if (this.minStack.length === 0 || val <= this.minStack[this.minStack.length - 1]) {
this.minStack.push(val);
}
}
pop() {
const val = this.stack.pop();
// If the popped value was the current minimum, the
// next entry down in minStack is the new minimum.
if (val === this.minStack[this.minStack.length - 1]) {
this.minStack.pop();
}
}
top() {
return this.stack[this.stack.length - 1];
}
getMin() {
return this.minStack[this.minStack.length - 1];
}
}The monotonic stack variant, which answers next greater and next smaller queries, has full templates on the Monotonic Stack template page . The problems on the practice problems page that use it, Daily Temperatures, Largest Rectangle in Histogram, and Trapping Rain Water, are solved with that template.
Now head to the practice problems to apply these templates to real interview questions.