Monotonic Stacks: Next Greater Element & Histogram Area Patterns
Monotonic Stacks: Next Greater Element & Histogram Area Patterns
A Monotonic Stack is a specialized stack whose elements are strictly maintained in a sorted monotonic order—either strictly increasing or strictly decreasing. This pattern is the secret weapon for solving range-lookup problems (like Next Greater Element, Daily Temperatures, and Largest Rectangle in Histogram) in single-pass $O(n)$ linear time instead of brute-force $O(n^2)$.
1. Real-World Analogy: Waiting for a Taller Person
Imagine people standing in a line waiting at a bus stop:
- A person looks forward into the distance.
- Shorter people in front of them are completely blocked from view by the first person who is taller than them.
- Once a giant steps into the line, all shorter people standing behind them are overshadowed. A monotonic decreasing stack maintains this exact line of sight!
2. The Two Types of Monotonic Stacks
- 1Monotonically Increasing Stack: Elements from bottom to top are in increasing order ($1 \to 3 \to 5 \to 8$).
- Used to find the Previous/Next Smaller Element.
- 1Monotonically Decreasing Stack: Elements from bottom to top are in decreasing order ($8 \to 5 \to 3 \to 1$).
- Used to find the Previous/Next Greater Element.
3. Classic Problem: Daily Temperatures
Given an array of daily temperatures temperatures, return an array answer such that answer[i] is the number of days you have to wait after the $i$-th day to get a warmer temperature. If there is no future day with a warmer temperature, keep answer[i] == 0.
Python 3 Implementation:
Modern JavaScript / TypeScript Implementation:
4. Trace Table: temperatures = [73, 74, 75, 71, 69, 72, 76, 73]
| Day ($i$) | Temp | Stack Before (Indices) | While Loop Condition (top_temp < curr) | Pops & Result Updates | Stack After |
|---|---|---|---|---|---|
| 0 | 73 | [] | False | None | [0] |
| 1 | 74 | [0] (73) | 73 < 74 (True) | Pop 0 $\to$ res[0] = 1 - 0 = 1 | [1] |
| 2 | 75 | [1] (74) | 74 < 75 (True) | Pop 1 $\to$ res[1] = 2 - 1 = 1 | [2] |
| 3 | 71 | [2] (75) | 75 < 71 (False) | None | [2, 3] |
| 4 | 69 | [2, 3] (75, 71) | 71 < 69 (False) | None | [2, 3, 4] |
| 5 | 72 | [2, 3, 4] (75, 71, 69) | 69 < 72, then 71 < 72 | Pop 4 $\to$ res[4]=1, Pop 3 $\to$ res[3]=2 | [2, 5] |
| 6 | 76 | [2, 5] (75, 72) | 72 < 76, then 75 < 76 | Pop 5 $\to$ res[5]=1, Pop 2 $\to$ res[2]=4 | [6] |
| 7 | 73 | [6] (76) | 76 < 73 (False) | None | [6, 7] |
Final Result: [1, 1, 4, 2, 1, 1, 0, 0]. Every index is pushed and popped at most once: $O(n)$ time!
Multiple Choice Questions
Queues: FIFO Mechanics, Circular Buffers & Double-Ended Queues (Deque)
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.