Foundation · Module 11 · Lesson 4
Monotonic stack
Next greater/smaller and contribution ranges.
Lesson 61 of 123
1d streakMonotonic Stack: Finding Next Greater / Smaller Elements
A Monotonic Stack maintains its elements in strictly sorted order (either strictly increasing or strictly decreasing). It solves problems of the form: "For each element, find the nearest element to its right or left that is greater or smaller than it" in $O(n)$ total time instead of brute-force $O(n^2)$.
Goal: Find next greater element to the right for each number.
Scan from Right to Left (index 4 -> 3 -> 2 -> 1 -> 0):
1. Element 3 (idx 4): Stack is empty -> NGE is -1. Push 3. Stack: [ 3 ]
2. Element 4 (idx 3): Top 3 is smaller -> Pop 3. Stack empty -> -1. Push 4. Stack: [ 4 ]
3. Element 2 (idx 2): Top 4 is greater -> NGE is 4. Push 2. Stack: [ 4, 2 ]
4. Element 1 (idx 1): Top 2 is greater -> NGE is 2. Push 1. Stack: [ 4, 2, 1 ]
5. Element 2 (idx 0): Top 1 is <= 2 -> Pop 1. Top 2 is <= 2 -> Pop 2.
Top 4 is greater -> NGE is 4. Push 2. Stack: [ 4, 2 ]
Final Output: [4, 2, 4, -1, -1]
Total Time: Every element is pushed once and popped at most once = O(n) linear time!public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
int[] result = new int[n];
Deque<Integer> stack = new ArrayDeque<>(); // stores values (or indices)
for (int i = n - 1; i >= 0; i--) {
// Pop all elements that are smaller than or equal to current number
while (!stack.isEmpty() && stack.peek() <= nums[i]) {
stack.pop();
}
result[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i]);
}
return result;
}Use it when
Use a Monotonic Stack when you need the nearest boundary (greater or smaller element) to the left or right: Daily Temperatures, Stock Span, Next Greater Element, Largest Rectangle in Histogram.
Reconsider when
Reconsider when you need the global maximum or minimum across an entire window (use a Monotonic Deque or Heap instead).
Cost Model
Complexity & Trade-offs
When to use it
- Nested parsing, undo, arrival order, buffering, and nearest-greater queries.
- BFS frontiers and producer/consumer scheduling.
- Maintaining range extremes or constrained access.
Common mistakes
- Reading from an empty structure.
- Confusing the logical front with an array index in a circular buffer.
- Missing the amortized argument for transfers or monotonic pops.
Practice prompts
- Reproduce the worked Monotonic stack example without looking at the trace.
- Change one input condition and explain whether the Monotonic stack invariant still holds.
- Implement the approach, derive its cost, and compare it with a straightforward baseline.
Mastery check