Grokking the Coding Interview: Patterns for Coding Questions
Vote

0% completed

Introduction to Monotonic Stack

Core idea

How it works

Recognize it when

The template

Variants in this chapter

Watch out for

How this compares with nearby patterns

Key takeaways

You are given a list of daily temperatures. For each day, find how many days you must wait for a warmer temperature.

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

A simple solution starts at every day and scans forward until it finds a warmer day.

In the worst case, each scan reaches the end of the list. This gives O(N²) time.

We can avoid repeating these scans by keeping only the days that are still waiting for an answer.

When temperature 72 arrives, it answers the days with temperatures 71 and 69. It does not answer the day with 75.

The waiting temperatures stay in decreasing order:

75, 71, 69

When a warmer value arrives, remove every smaller waiting value. Each removal completes one answer.

This ordered stack is called a monotonic stack.

Core idea

A Monotonic Stack keeps its values in increasing or decreasing order.

Before adding a new item, pop items that would break the required order.

Each item in the stack is waiting for a future value. A pop usually means that the waiting item has found its answer.

How it works

For the next warmer day, follow these steps:

  1. Create an empty stack.
  2. Store indices in the stack, not only temperatures.
  3. Read the temperatures from left to right.
  4. Compare the current temperature with the temperature at the top stack index.
  5. While the current temperature is warmer, pop the top index.
  6. Record the distance between the current index and the popped index.
  7. Push the current index.
  8. Leave unanswered positions at their default value after the loop.
The stack stays in decreasing order, and a warmer day can answer several waiting days at once.
The stack stays in decreasing order, and a warmer day can answer several waiting days at once.

The code contains a while loop inside a for loop, but the total time is not O(N²).

Each index is pushed exactly once. Each index is popped at most once. Therefore, the total time complexity is O(N).

The stack may store all indices in the worst case, so the space complexity is O(N).

Store indices because they provide both position and value. The value can be read as temperatures[index].

Recognize it when

A Monotonic Stack may be useful when:

  • The problem asks for the next greater or next smaller value.
  • The problem asks for the previous greater or previous smaller value.
  • The wording asks how long you must wait.
  • The answer is a distance, span, or nearest position.
  • Each element contributes as a minimum or maximum across subarrays.
  • You remove digits or values to make a result as small or large as possible.
  • Your first solution scans forward from every position.

Do not use this pattern when:

  • Only the most recent item matters and no sorted order is required. Use a basic Stack.
  • You need a maximum or minimum inside a moving window. Use a Monotonic Queue.
  • The input is already sorted and you need a target. Use Binary Search or Two Pointers.
  • You need a general sorted collection with insert and delete operations. Use another ordered data structure.

The template

function nextGreater(values):
    answer = array filled with a default value
    stack = empty

    for i from 0 to length(values) - 1:
        while stack is not empty and values[i] > values[top of stack]:
            j = pop from stack
            answer[j] = i - j

        push i onto stack

    return answer

Two choices define the problem:

  1. The comparison operator decides whether the stack increases or decreases.
  2. The code inside the pop decides what answer to record.

Using > finds the next greater value and keeps waiting values in decreasing order.

Using < finds the next smaller value and keeps waiting values in increasing order.

The answer may be a distance, a value, an index, or a contribution to a total.

Variants in this chapter

VariantWhat a pop meansProblems in this chapter
Find the next greater valuethe popped position has found its answerNext Greater Element, Daily Temperatures
Remove matching neighboursthe top item and current item cancel each otherRemove All Adjacent Duplicates In String, Remove All Adjacent Duplicates in String II
Improve the resultthe popped item makes the result worseRemove K Digits, Remove Nodes From Linked List
Count contributionspopping reveals the range where an item is minimumSum of Subarray Minimums

Learn the next-greater variant first. The other variants change the work performed during each pop.

Watch out for

  • Choosing the wrong direction. Decide whether you need greater or smaller values before choosing the comparison.
  • Storing only values. Store indices when you need distances or must distinguish duplicate values.
  • Forgetting unanswered positions. Items left in the stack never found a matching future value.
  • Handling equal values incorrectly. > and >= produce different answers when duplicates exist.
  • Calling the algorithm quadratic. Every index is pushed once and popped at most once.
  • Reading the top of an empty stack. Always check that the stack contains an item first.

How this compares with nearby patterns

If the problem needs...Use...
the next or previous greater or smaller valueMonotonic Stack
matching, nesting, or undoStack
a maximum or minimum inside each moving windowMonotonic Queue
a contiguous range that grows and shrinksSliding Window

A Monotonic Queue also keeps items ordered. It can remove items from the front when they leave a sliding window.

Key takeaways

  • A monotonic stack keeps waiting items in increasing or decreasing order.
  • Pop items that break the required order before pushing the current item.
  • A pop usually completes one waiting answer.
  • Store indices when the answer needs positions or distances.
  • Each index is pushed once and popped at most once.
  • The total time is O(N), and the worst-case space is O(N).

Now apply this pattern to Remove Nodes From Linked List.

Kinshuk Agrawal

Kinshuk Agrawal

· 3 years ago

It would be nice to have such a comprehensive explanation + pseudo code for every pattern

K

karrad

· 3 years ago

  • Input: nums1 = [9,7,1]nums2 = [1,7,9,5,4,3]
  • Output: [-1,9,7]

In this example, we first take 9 and compare to every number to right of 9 in nums2. No number >9 so -1

Then 7. The 1st number to right of 7 (i.e only consider last 4 numbers in nums2) is 9

Now we consider 1. If we go by the same logic, we should only consider 5,4,3 in nums2. Why is the answer 7? Should it not be 5?

Thanks

M

Show 2 replies
A

Anand Mohan

· 3 years ago

There seems to be a mistake in the image. We are using monotonically decreasing stack.

Reading Progress

0%


Vote for new content

On This Page

Core idea

How it works

Recognize it when

The template

Variants in this chapter

Watch out for

How this compares with nearby patterns

Key takeaways