Core Idea: LIFO (Last-In-First-Out). Process elements where the most recent item matters, or where a future element resolves something about a past element.
Past Depends on Future: When you can't resolve an element until you see a future element, push it to stack. When you find the "answer" for stack elements, pop and process them.
Why Not Just Array? Stack enforces the "most recent first" discipline. When processing, you only care about the top - O(1) access to the relevant element.
Goal: Check if brackets are properly matched and nested.
Why Stack? Innermost bracket must close first. When we see ')', we need the most recent '(' - that's exactly what stack top gives us. LIFO matches nesting structure perfectly.
Key Insight: Push opening brackets. When closing bracket arrives, stack top must be matching opener. If not, or stack empty, invalid.
Don't Forget:
Check stack is empty at end - unmatched openers are invalid.Goal: Stack with O(1) push, pop, top, AND getMin.
Why Two Stacks? Main stack for values. Monotonic decreasing stack for minimums. When we push a new minimum, it goes on both. When we pop, if it equals mono top, pop both.
Key Insight: Larger values pushed after a minimum will be popped before that minimum. So we don't need to track them in mono stack - they can never be the min while the smaller value exists.
Mono Stack Insight:
Only track values that could be min at some point.Goal: Evaluate postfix expression like ["2","1","+","3","*"] = 9.
Why Stack? In RPN, operators act on the two most recent operands. Stack naturally accumulates operands, and operator pops exactly what it needs. Result becomes new operand.
Key Insight: Numbers → push. Operator → pop two, compute, push result. Final answer is last item on stack.
Order Matters:
For - and /, it's a op b where a is deeper in stack (second-to-top).Goal: For each day, find days until a warmer temperature.
Why Stack? Classic "next greater element" pattern. We can't answer "when is next warmer day?" until we see that warmer day. Push indices to stack; when warmer day arrives, it resolves all cooler days waiting on stack.
Key Insight: Stack holds indices of days "waiting for answer". When temp[i] > temp[stack.top], we found the answer for stack.top. Pop and record distance. Stack stays monotonic decreasing (in temperature).
Next Greater Element:
Mono decreasing stack. Pop when you find something greater.Goal: Count how many car fleets arrive at destination.
Why Stack-like? Sort by position (closest to target first). For each car, calculate time to reach target. If a car behind takes LESS time, it would catch up and merge (same fleet). If MORE time, separate fleet.
Key Insight: Process from closest to target. Stack tracks fleet arrival times. If current car's time ≤ stack top, it merges (catches up). If time > stack top, it's a new fleet - push it.
Key Formula:
time_to_target = (target - position) / speed. Compare times, not positions.Goal: Find largest rectangle area in histogram bars.
Why Stack? For each bar, we need its left and right boundaries (next smaller elements). When we see a shorter bar, it's the right boundary for all taller bars on stack. The bar below in stack is the left boundary.
Key Insight: Stack holds indices in increasing height order. When heights[i] < stack top, we found right boundary for top. Pop, calculate area using: height × (rightBound - leftBound - 1). Left bound is new stack top (or -1 if empty).
Next Smaller Element:
Mono increasing stack. Pop when you find something smaller.Goal: Calculate total water trapped between bars after rain.
Why Stack? Water is trapped between two walls with a lower region between them. We can't know the right wall until we see it. Stack holds bars waiting for a taller bar to appear (their right boundary).
Key Insight: Unlike prefix-max approach (column by column), stack calculates water layer by layer horizontally. Each pop handles one horizontal layer of water between two walls.
When we pop from stack, we have access to three critical elements:
Why This Works: The monotonic decreasing property guarantees that after popping the bottom, the new top is taller (or equal). Combined with the current bar being taller than bottom, we have a valid "container" with walls on both sides.
Array approach (prefix/suffix): For each column, calculate vertical water height = min(leftMax, rightMax) - height.
Stack approach: Fill water horizontally between two walls, layer by layer from bottom up. Same rightBound triggers multiple pops, each pop adds one layer on top of the previous.
Key: Within one rightBound's pop loop, successive pops add layers vertically. Each pop has a taller leftBound, filling a wider region. Stops when rightBound becomes the limiting wall.
Layer-by-Layer:
Each pop calculates one horizontal water layer. The same "pool" may generate multiple pops as we fill it layer by layer from bottom up.Must Have Left Wall:
After popping bottom, if stack is empty there's no left wall - no water can be trapped. Always check stack not empty before calculating.Use When: Validating balanced structures (parentheses, tags, nested calls).
Template: Push openers, pop and match on closers.
Example: Valid Parentheses.
Use When: Evaluating RPN, calculators, parsing expressions.
Template: Push operands, pop for operators, push result.
Example: Evaluate RPN.
Use When: "Find next larger/warmer/higher element."
Template: Push to stack. When greater found, pop and resolve.
Example: Daily Temperatures.
Use When: "Find boundaries", "largest rectangle", "next smaller".
Template: Push to stack. When smaller found, pop and resolve.
Example: Largest Rectangle in Histogram.
Use When: Need O(1) min/max while maintaining stack operations.
Template: Second stack tracks min/max at each state.
Example: Min Stack.
Common Thread:
Stack = "most recent matters" or "waiting for future to resolve past". Monotonic stacks efficiently find next greater/smaller by maintaining sorted order.Finding next greater or next smaller element for each position in O(n).
Store Indices: Almost always store indices, not values. Need index to calculate distances and access original values.
Leftover Items: Elements remaining on stack have no next greater/smaller. Handle based on problem (often default to 0 or n).
For problems needing both left and right boundaries (rectangles, water):
Why It Works: Monotonic property ensures the element below the popped one is always a valid boundary - it's the nearest element in that direction satisfying the condition (smaller for increasing, larger for decreasing).