PROBLEM-SOLVING PATTERNS / ALGORITHM BRIEF

Monotonic stack

A monotonic stack keeps its elements in increasing or decreasing order.

IntermediatePhase 03 / Topic 9 of 10Mental modelComplexityEdge cases
01

Overview

A monotonic stack keeps its elements in increasing or decreasing order. Before pushing a new element, you pop every element that breaks the order. The moment an element is popped is exactly when you discover its next greater (or smaller) element: the one that caused the pop.

This turns 'for each element, find the next larger element' from O(n^2) into O(n), because each element is pushed once and popped at most once. It is the key to daily temperatures, stock span, largest rectangle in a histogram, and trapping rain water.

People in a queue looking forward

Each person in a line looks ahead to find the first taller person. When a tall person arrives, everyone shorter standing in front of them in the stack of waiting people has found their answer and leaves the stack.

02

When to use it

  • For each element, find the next or previous greater or smaller element.
  • How far can each element extend left or right before a larger / smaller value blocks it.
  • Sum or count over all subarrays of their minimum or maximum.
  • Build the lexicographically smallest result by removing characters or digits.
03

Problem patterns it solves

Next greater / smaller element

Recognize it when: for each element, the next element that is bigger or smaller.

  • 496. Next Greater Element I
  • 503. Next Greater Element II
  • 739. Daily Temperatures
  • 1475. Final Prices With a Special Discount
Previous greater (span)

Recognize it when: how many consecutive previous elements are smaller or equal.

  • 901. Online Stock Span
  • 1019. Next Greater Node In Linked List
Area bounded by smaller bars

Recognize it when: largest rectangle, maximal rectangle of 1s.

  • 84. Largest Rectangle in Histogram
  • 85. Maximal Rectangle
  • 1793. Maximum Score of a Good Subarray
Water between walls

Recognize it when: water trapped between higher bars.

  • 42. Trapping Rain Water
Sum of subarray minimums / maximums

Recognize it when: contribution of each element as min or max over all subarrays.

  • 907. Sum of Subarray Minimums
  • 2104. Sum of Subarray Ranges
Greedy removal for smallest result

Recognize it when: remove k digits or duplicate letters to get the smallest string.

  • 402. Remove K Digits
  • 316. Remove Duplicate Letters
  • 1081. Smallest Subsequence of Distinct Characters
04

Where it is used in real software

Stock charts

Stock span (days since a higher price) and next-higher-price calculations in trading analytics use monotonic stacks.

Skyline and visibility

Determining which buildings are visible from a viewpoint, or computing a city skyline, removes buildings hidden behind taller ones.

Compilers

Operator-precedence parsing pops lower-precedence operators, a close relative of the monotonic stack.

Image processing

Finding the largest all-white rectangle in a binary image uses the histogram-rectangle technique row by row.

05

Key terms

Monotonic decreasing stack
Values decrease from bottom to top; used for next greater element.
Monotonic increasing stack
Values increase from bottom to top; used for next smaller element and histogram areas.
Store indexes
Push indexes so you can compute distances and look up values.
Sentinel
A final 0 or infinity pushed at the end to flush the remaining elements.
06

How it works, step by step

  1. 1
    Pick the order

    Next greater: keep a decreasing stack. Next smaller: keep an increasing stack.

  2. 2
    For each index i

    While the stack is not empty and nums[i] breaks the order with nums[top], pop top.

  3. 3
    Record the answer for the popped index

    nums[i] is the next greater (or smaller) element of top; distance is i - top.

  4. 4
    Push i

    i waits on the stack until something larger arrives.

  5. 5
    Leftover indexes

    Elements still on the stack have no next greater element: answer -1 or 0.

Daily temperatures on [73, 74, 75, 71, 69, 72, 76, 73]
Step 1 / 6
73
0
74
1
75
2
71
3
69
4
72
5
76
6
73
7

STEP 1i = 0: push index 0. Stack = [73].

07

Daily temperatures trace

temps = [73, 74, 75, 71, 69, 72, 76, 73]

Step 1 / 8
itempPopped (index: answer)Stack after (temps)
073-[73]
1740: 1[74]
2751: 1[75]
371-[75, 71]
469-[75, 71, 69]
5724: 1, 3: 2[75, 72]
6765: 1, 2: 4[76]
773-[76, 73]

NOWi: 0 | temp: 73 | Popped (index: answer): - | Stack after (temps): [73]

answer = [1, 1, 4, 2, 1, 1, 0, 0]. Indexes 6 and 7 remain on the stack with no warmer day, so they stay 0.

08

Implementation

function dailyTemperatures(temps) {  const answer = new Array(temps.length).fill(0);  const stack = []; // indexes, temperatures decreasing  for (let i = 0; i < temps.length; i++) {    while (stack.length && temps[i] > temps[stack.at(-1)]) {      const j = stack.pop();      answer[j] = i - j;    }    stack.push(i);  }  return answer;} function largestRectangleArea(heights) {  const stack = []; // indexes, heights increasing  let best = 0;  for (let i = 0; i <= heights.length; i++) {    const h = i === heights.length ? 0 : heights[i]; // sentinel flushes the stack    while (stack.length && heights[stack.at(-1)] > h) {      const height = heights[stack.pop()];      const left = stack.length ? stack.at(-1) + 1 : 0;      best = Math.max(best, height * (i - left));    }    stack.push(i);  }  return best;} // 402. Remove K Digits: keep an increasing stack of digitsfunction removeKdigits(num, k) {  const stack = [];  for (const d of num) {    while (k > 0 && stack.length && stack.at(-1) > d) {      stack.pop();      k--;    }    stack.push(d);  }  stack.length -= k; // remove the rest from the end  const result = stack.join("").replace(/^0+/, "");  return result || "0";}
09

Complexity and performance

TimeO(n)

Each index pushed once, popped at most once.

SpaceO(n)

Stack in the worst case (sorted input).

Brute forceO(n^2)

Scan right from each element.

10

Trade-offs

Strict vs non-strict comparisons

With duplicates, use > on one side and >= on the other so each subarray is counted once in contribution problems.

Two passes vs one

Some problems need previous and next boundaries; compute them in two passes or derive both when popping.

11

Variants and related techniques

Circular arrays

Iterate 2n times using i % n (Next Greater Element II).

Monotonic deque

When elements must also expire (sliding windows), use a deque instead of a stack.

Contribution technique

For each element, count subarrays where it is the minimum: (i - prevSmaller) x (nextSmaller - i).

12

Common mistakes

  • Pushing values instead of indexes.

    Fix: Indexes give distances and widths; values alone do not.

  • Forgetting leftover elements.

    Fix: Use a sentinel or handle the remaining stack after the loop.

  • Wrong width in histogram.

    Fix: Width = i - (new top + 1), or i when the stack becomes empty.

  • Double counting with duplicates.

    Fix: Make one side strict and the other non-strict.

13

Interview questions

Why is the monotonic stack O(n) with a nested while loop?

Every index is pushed exactly once and popped at most once. The total number of pops across the whole run is at most n.

How do you decide increasing or decreasing?

To find the next greater element, pop smaller elements, so the stack stays decreasing. To find the next smaller element, pop larger elements, so it stays increasing.

14

Practice problems

ProblemDifficultyWhat it trains
496. Next Greater Element IEasyStack plus map.
739. Daily TemperaturesMediumDistances.
901. Online Stock SpanMediumPrevious greater with merged spans.
402. Remove K DigitsMediumGreedy increasing stack.
907. Sum of Subarray MinimumsMediumContribution counting.
84. Largest Rectangle in HistogramHardWidths from boundaries.
42. Trapping Rain WaterHardBounded water layers.