A Last-In-First-Out pile: push on top, pop off the top, peek without removing — every operation O(1).
A stack is a pile where you only ever touch the top. You push a value on, pop the top one off, or peek at it without removing it — and that's the entire interface. The rule it enforces is LIFO: *Last In, First Out*. The most recent thing added is the first to leave, exactly like a stack of plates.
x on top of the pile.Each one touches only the top, so each is constant time regardless of how tall the stack grows. Backed by a dynamic array, push and pop are just appending to and removing from the end.
class Stack {
constructor() { this.items = []; }
push(x) { this.items.push(x); } // add to top
pop() { return this.items.pop(); } // remove top
peek() { return this.items[this.items.length - 1]; }
get isEmpty() { return this.items.length === 0; }
}A classic use: check whether ()[]{} are balanced. Push every opening bracket; on a closing bracket, pop and check it matches. If the pop doesn't match — or the stack is empty when you need to pop, or non-empty at the end — the string is unbalanced. The stack naturally pairs each closer with the *most recent* unmatched opener, which is exactly LIFO.
function isBalanced(s) {
const stack = [];
const pairs = { ')': '(', ']': '[', '}': '{' };
for (const ch of s) {
if (ch === '(' || ch === '[' || ch === '{') stack.push(ch);
else if (ch in pairs) {
if (stack.pop() !== pairs[ch]) return false;
}
}
return stack.length === 0; // nothing left unmatched
}pop or peek on an empty stack has no top to return — a common bug. Always guard with an isEmpty check (or accept the undefined/error your language gives) before relying on the result.