CMD Guide
HomeDSAStack

Introduction to Monotonic Stack

A monotonic stack is a stack that a caller keeps sorted (increasing or decreasing, bottom to top) by popping any elements that would break the order before pushing — because each element is compared against, and permanently removes, only the elements it beats, the total number of comparisons across the whole array is bounded by the number of pushes plus pops, giving O(n) instead of the O(n²) of comparing every pair.

Recognize the pattern

Brute force → optimal

Brute force: for each index i, scan rightward (or leftward) until you find the first element satisfying the relation. Worst case (strictly decreasing array, looking for next greater) every scan runs to the end: O(n²) time, O(1) extra space.

Optimal (monotonic stack): walk the array once, maintaining a stack of indices whose values are still "undecided" (no next-greater found yet), kept in decreasing order of value from bottom to top. For each new value, pop every stacked index whose value is smaller — the new value IS their answer. Then push the current index. O(n) time, O(n) space.

Complexity, derived

Let n = array length. Each index is pushed onto the stack exactly once (in the single left-to-right pass) and can therefore be popped at most once over the whole run — it never gets pushed again after popping. So total pushes = n, total pops ≤ n. The while-loop body inside the for-loop runs once per pop, so summed over all iterations the inner loop body executes ≤ n times, not n times per outer iteration. Total work = O(n) pushes + O(n) pops = O(n) time. The stack holds at most n indices → O(n) space (plus the O(n) output array).

Worked example — Next Greater Element

Array: [2, 1, 2, 4, 3]. Find next greater element to the right for each index; stack holds indices, kept so values are decreasing bottom→top.

ivalactionstack after (indices)NGE resolved
02push 0[0]
111<val@0(2), push 1[0,1]
22pop 1 (1<2)→NGE[1]=2; top now 0 (val 2, not < 2, stop); push 2[0,2]NGE[1]=2
34pop 2(2<4)→NGE[2]=4; pop 0(2<4)→NGE[0]=4; push 3[3]NGE[2]=4, NGE[0]=4
433<val@3(4), push 4[3,4]

End of array: remaining stack indices [3,4] get NGE = -1 (none found). Final: [4, 2, 4, -1, -1].

Java — Next Greater Element

int[] nextGreater(int[] nums) {
    int n = nums.length;
    int[] res = new int[n];
    Arrays.fill(res, -1);
    Deque<Integer> stack = new ArrayDeque<>(); // holds indices
    for (int i = 0; i < n; i++) {
        while (!stack.isEmpty() && nums[stack.peek()] < nums[i]) {
            res[stack.pop()] = nums[i];
        }
        stack.push(i);
    }
    return res;
}

Pitfalls

When to use / when not — trade-offs

Use a monotonic stack when the problem needs, for every element, the nearest element in one direction satisfying an order relation — it turns O(n²) pairwise comparison into O(n). Compare with alternatives:

Takeaways

Recall: Why is the total runtime O(n) even though there's a while-loop nested inside a for-loop?

🎯 Drill Ladder — survive the follow-ups

L0 · A monotonic stack maintains elements in a strict sorted order (increasing or decreasing) to solve next-greater-element problems in O(n) time.

L1 · ⑤ Adversary/Edge — “The array contains multiple duplicate values. Should the monotonic stack store duplicate values or discard/process them?”
Trap: Always discard duplicate elements as they violate monotonicity.
Bar: Store indices on the stack instead of literal values; check monotonicity using arr[stack.peek()] < arr[i] (strict) or <= (non-strict) to handle duplicates correctly without losing index alignment. Monotonic Stack

L2 · ② Failure — “You run the next-greater-element algorithm on a strictly decreasing array (e.g. [5, 4, 3, 2, 1]). What is the space complexity of the stack?”
Trap: O(1) space because no element finds a greater neighbor.
Bar: Since no element finds a greater neighbor, no element is popped; all N elements are pushed, creating a worst-case O(N) space footprint, though the time complexity remains O(N). Monotonic Stack

L3 · ③ Scale — “The input is a circular array (the next element of the last element is the first element). How do you resolve next-greater-elements in O(N) time and O(N) space?”
Trap: Duplicate the array to make it size 2N, then run standard monotonic stack.
Bar: Duplicating the array allocates O(N) physical memory; simulate a 2N array by running the loop from 0 to 2N-1 and accessing the array using modulo indexing (i % N), preserving space limits. Monotonic Stack

L4 · ① Concurrency — “Can you parallelize a monotonic stack algorithm across multiple CPU cores for a single array?”
Trap: Divide the array into chunks and run the monotonic stack on each chunk concurrently.
Bar: Monotonic stack state depends on global scan history; partition the array, compute monotonic stacks locally on each chunk, and resolve boundary crossings in a merging phase. Monotonic Stack

L5 · ⑥ Cost/Simplicity — “Why use a monotonic stack when a nested loop (brute force) is easier to implement?”
Trap: Monotonic stack is always faster.
Bar: For small inputs (N < 20), the nested loop has better instruction cache locality and no stack allocation overhead; reach for monotonic stack when N is large and you need O(N) time complexity. Monotonic Stack

The floor keeps dropping: How do you modify a monotonic stack to find the largest rectangular area in a histogram in one pass?

Self-locate: died at L1 → you present mid-level; L4+ → staff signal.

Facing any new concept? Hit it with the six: concurrent? failing? at 100×? over time? adversarial? worth the cost? — that's the interviewer's whole playbook.


Pattern popularized through LeetCode's Next Greater Element / Daily Temperatures / Largest Rectangle in Histogram problem family; complexity argument via amortized analysis (aggregate method), as in CLRS Ch. 17.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction to Monotonic Stack? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction to Monotonic Stack** (DSA) and want to truly understand it. Explain Introduction to Monotonic Stack from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction to Monotonic Stack** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction to Monotonic Stack** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction to Monotonic Stack** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes