Courses › Coding Interviews › Patterns
Monotonic Stack
Next greater element, histograms and stock spans in O(n).
A monotonic stack keeps its elements in sorted order (increasing or decreasing). Each new element pops everything it "beats", and those pops are where the answers come from. It turns many O(n²) "look left/right for the next bigger thing" problems into O(n).
When to use it
- Next greater / next smaller element (to the right or left)
- "How many days until a warmer temperature?"
- Largest rectangle in a histogram, maximal rectangles
- Stock span, trapping rain water
- Removing digits to make the smallest number
Template: next greater element
Keep a stack of indices whose answer is still unknown, with values decreasing from bottom to top. When a bigger value arrives, it's the answer for everything smaller on the stack.
def next_greater(nums):
result = [-1] * len(nums)
stack = [] # indices, values decreasing
for i, x in enumerate(nums):
while stack and nums[stack[-1]] < x:
result[stack.pop()] = x
stack.append(i)
return resultDaily temperatures is the same loop with result[j] = i - j (distance instead of value).
Why it's O(n)
The inner while loop looks quadratic, but every index is pushed once and popped at most once, so the total work across the whole loop is O(n). Mention this amortized argument when you state the complexity.
Choosing the direction
For "previous greater/smaller", the answer for the current element is whatever remains on top after popping.
Largest rectangle in a histogram
Maintain an increasing stack of bar indices. When a shorter bar arrives, each popped bar's rectangle extends from the new stack top + 1 to the current index − 1:
def largest_rectangle(heights):
stack, best = [], 0
for i, h in enumerate(heights + [0]): # sentinel flushes the stack
while stack and heights[stack[-1]] > h:
height = heights[stack.pop()]
left = stack[-1] + 1 if stack else 0
best = max(best, height * (i - left))
stack.append(i)
return best[!TIP] Practice Daily Temperatures · Trapping Rain Water