Mastering Monotonic Stack Interview Problems: A Complete Guide
Learn monotonic stack pattern with real interview questions, code examples, and debugging tips.
20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.
- ✓Basic understanding of stack data structure (push, pop, peek).
- ✓Familiarity with arrays and iteration.
- ✓Knowledge of time and space complexity analysis.
- Monotonic stack maintains elements in increasing or decreasing order.
- Used for problems involving next greater/smaller elements, sliding window maximum, and histogram area.
- Time complexity is typically O(n) with O(n) space.
- Key operations: push, pop while maintaining monotonic property.
- Common variants: increasing stack for next smaller, decreasing for next greater.
Imagine you're organizing a line of people by height. A monotonic stack is like a bouncer who only lets people in if they are taller (or shorter) than the last person. This helps quickly find who is the next taller person in line.
When you're in a coding interview and the interviewer asks you to find the next greater element for every element in an array, your heart might skip a beat. But what if you could solve it in O(n) time with a simple stack? That's the power of the monotonic stack pattern.
Monotonic stack is a technique where you maintain a stack that is either strictly increasing or decreasing. It's a go-to pattern for problems involving 'next greater', 'next smaller', 'previous greater', or 'previous smaller' elements. It also appears in more complex problems like 'Largest Rectangle in Histogram' and 'Trapping Rain Water'.
In this guide, we'll break down the monotonic stack pattern, walk through classic interview problems with detailed solutions, and share tips to ace your interview. By the end, you'll be able to recognize and solve monotonic stack problems with confidence.
What is a Monotonic Stack?
A monotonic stack is a stack that maintains its elements in a specific order — either strictly increasing or strictly decreasing. It's used to solve problems where you need to find the next greater or smaller element efficiently.
Types: - Increasing stack: Elements are in increasing order from bottom to top. Used for next smaller element. - Decreasing stack: Elements are in decreasing order. Used for next greater element.
How it works: You iterate through the array. For each element, you pop elements from the stack that violate the monotonic property. The popped elements' results are updated using the current element. Then you push the current element onto the stack.
Time Complexity: O(n) — each element is pushed and popped at most once. Space Complexity: O(n) — stack can hold up to n elements.
Classic Problem: Next Greater Element I
Problem: Given two arrays nums1 and nums2, where nums1 is a subset of nums2, find the next greater element for each element in nums1 within nums2.
Approach: Use a monotonic decreasing stack on nums2 to precompute next greater elements for all elements. Store in a hash map. Then answer for nums1 in O(1) each.
Steps: 1. Create a hash map next_greater. 2. Iterate through nums2 with a decreasing stack. 3. For each popped element, set its next greater to current element. 4. After loop, remaining elements have no next greater (store -1). 5. Build result for nums1 using the map.
Complexities: Time O(n + m), Space O(n).
Classic Problem: Daily Temperatures
Problem: Given an array of temperatures, return an array such that answer[i] is the number of days you have to wait until a warmer temperature. If no warmer day, answer[i] = 0.
Approach: Use a decreasing stack of indices. When a warmer temperature is found, pop indices and compute the difference.
Steps: 1. Initialize result array with zeros. 2. Iterate through temperatures with index i. 3. While stack not empty and temperatures[stack[-1]] < temperatures[i]: - Pop index j. - result[j] = i - j. 4. Push i onto stack.
Complexities: Time O(n), Space O(n).
Classic Problem: Largest Rectangle in Histogram
Problem: Given an array of bar heights, find the largest rectangle that can be formed in the histogram.
Approach: Use an increasing stack of indices. For each bar, pop bars taller than current, calculate area using current index as right boundary and the new top as left boundary.
Steps: 1. Append 0 to heights to handle remaining bars. 2. Iterate through heights with index i. 3. While stack not empty and heights[stack[-1]] > heights[i]: - Pop height h = heights[stack.pop()]. - Width = i if stack empty else i - stack[-1] - 1. - Update max area. 4. Push i.
Complexities: Time O(n), Space O(n).
Classic Problem: Trapping Rain Water
Problem: Given an array of non-negative integers representing elevation, compute how much water can be trapped after rain.
Approach: Use a decreasing stack. When a bar taller than the top is found, pop the top as a valley, and calculate water trapped using the new top as left boundary and current as right boundary.
Steps: 1. Initialize stack and water = 0. 2. Iterate through heights with index i. 3. While stack not empty and heights[stack[-1]] < heights[i]: - Pop top = stack.pop(). - If stack empty, break. - Distance = i - stack[-1] - 1. - Bounded height = min(heights[stack[-1]], heights[i]) - heights[top]. - Water += distance * bounded height. 4. Push i.
Complexities: Time O(n), Space O(n).
Advanced Problem: Sum of Subarray Minimums
Problem: Given an array, find the sum of minimums of all contiguous subarrays. Return result modulo 10^9+7.
Approach: For each element, find how many subarrays it is the minimum of. Use two passes with monotonic stack: one for previous smaller element (PSE) and one for next smaller element (NSE).
Steps: 1. Compute left[i] = distance to previous smaller element (strictly smaller). 2. Compute right[i] = distance to next smaller element (strictly smaller). 3. For each i, contribution = arr[i] left[i] right[i]. 4. Sum all contributions modulo MOD.
Complexities: Time O(n), Space O(n).
Interview Tips and Variations
Recognizing the Pattern: - Problem asks for 'next greater/smaller', 'previous greater/smaller', or 'nearest greater/smaller'. - Problem involves calculating something based on the nearest larger or smaller element. - Examples: Stock span, sliding window maximum (can use deque), maximum of minimums of every window size.
Common Variations: - Next Greater Element II (circular array): iterate twice. - Online Stock Span: maintain stack of (price, span). - Maximum Width Ramp: use decreasing stack of indices.
Interview Communication: 1. Start with brute force O(n²) and explain why it's suboptimal. 2. Introduce monotonic stack as optimization. 3. Walk through an example with a small array. 4. Discuss edge cases: empty, duplicates, decreasing/increasing order. 5. Analyze time and space complexity.
Common Mistakes: - Using wrong monotonic property (increasing vs decreasing). - Forgetting to handle remaining elements in stack. - Off-by-one errors in width calculations.
The Slow Stock Price Tracker
- Always consider worst-case input size.
- Monotonic stack can optimize many 'next greater' style problems.
- Profile your code with realistic data volumes.
- Use appropriate data structures to avoid quadratic time.
- Document assumptions about input constraints.
Print stack after each push/pop.Verify comparison: while stack and arr[stack[-1]] < arr[i].| File | Command / Code | Purpose |
|---|---|---|
| monotonic_stack_template.py | def next_greater_element(nums): | What is a Monotonic Stack? |
| next_greater_element_i.py | def nextGreaterElement(nums1, nums2): | Classic Problem |
| daily_temperatures.py | def dailyTemperatures(temperatures): | Classic Problem |
| largest_rectangle_histogram.py | def largestRectangleArea(heights): | Classic Problem |
| trapping_rain_water.py | def trap(height): | Classic Problem |
| sum_subarray_minimums.py | def sumSubarrayMins(arr): | Advanced Problem |
Key takeaways
Common mistakes to avoid
3 patternsUsing wrong monotonic property (e.g., increasing stack for next greater).
Forgetting to process remaining elements in stack after loop.
Off-by-one errors in width calculations for histogram and rain water.
Interview Questions on This Topic
Implement a function to find the next greater element for each element in an array. If no greater element, return -1.
Frequently Asked Questions
20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.
That's Coding Patterns. Mark it forged?
3 min read · try the examples if you haven't