The Monotonic Stack, Explained

A monotonic stack is an ordinary stack with one extra rule: its values are always in sorted order from bottom to top.

Before pushing a new value, you pop every value that would break the order. That single habit answers questions like "what is the next larger element?" for every position in one pass.

Increasing stack

Values grow from bottom to top. Each new value first pops everything larger than it.

Example: with the stack holding [1, 4, 6], pushing 3 pops 6 and 4, leaving [1, 3].

Every value that gets popped has just met the first smaller value to its right.

So an increasing stack is the tool for next smaller element problems.

It also finds the previous smaller element, which is whatever sits below a value once it is pushed.

Use it whenever you need the nearest smaller value on either side of each element.

Decreasing stack

Values shrink from bottom to top. Each new value first pops everything smaller than it.

Example: with the stack holding [9, 5, 2], pushing 7 pops 2 and 5, leaving [9, 7].

Each popped value has just found its next greater element, so this is the classic setup for "how many days until a warmer temperature".

Why it is fast

Every element is pushed exactly once and popped at most once, so the whole scan is O(n) even though there is a loop inside the loop.

The brute force alternative compares every element with every element to its right, which is O(n²).

Store indices instead of values when you need distances, such as the number of days between two temperatures.

When to reach for it

The problem asks about the nearest larger or smaller element to the left or right of every position, or about spans and ranges bounded by such elements.

You will not see it often, but when you do, it is very hard to come up with it on the spot.

MONOTONIC = ALWAYS IN ORDER

A monotonic stack keeps its values sorted from bottom to top.

Anything that would break the order is popped before a new value goes in.

1. Increasing Stack

Values grow from bottom to top.

Before pushing, pop every value larger than the new one.

Pushing 3 onto [1, 4, 6]:

Each popped value has found its next smaller element: 3.

2. Decreasing Stack

Values shrink from bottom to top.

Before pushing, pop every value smaller than the new one.

Pushing 7 onto [9, 5, 2]:

Each popped value has found its next greater element: 7.

3. Why Bother?

A monotonic stack answers a question for every element, like "which value to my right is the first one larger than me?", in a single pass.

Key idea: every element is pushed once and popped at most once. That caps the total work at 2n steps, so a problem that looks O(n²) becomes O(n).

4. The Template

Next greater element (decreasing stack)

answer = [-1] * len(nums)
stack = []                      # indices
for i, x in enumerate(nums):
    while stack and nums[stack[-1]] < x:
        answer[stack.pop()] = x
    stack.append(i)

Next smaller element (increasing stack)

answer = [-1] * len(nums)
stack = []
for i, x in enumerate(nums):
    while stack and nums[stack[-1]] > x:
        answer[stack.pop()] = x
    stack.append(i)

Only the comparison in the while line changes.

5. When to Use It

Look for problems about:

  • The next or previous greater element
  • The next or previous smaller element
  • Spans or ranges bounded by larger or smaller values
  • A brute force that compares each element with everything to its right

Tip: if you keep scanning left or right from every element to find a bigger or smaller one, a monotonic stack can usually replace that inner scan.

6. Practice Problems

  1. Daily Temperatures
  2. Next Greater Element I
  3. Online Stock Span
  4. Largest Rectangle in Histogram
  5. Car Fleet

Remember: monotonic stack problems are not common, but they are almost impossible to solve on the spot if you have never seen the pattern.