Skip to content
intermediatePhase 2 · Linear Structures

Monotonic Stack

Use monotonic stacks for finding next greater/smaller elements efficiently.

1h
5 problems
Topic Progress0%

Monotonic Stack Introduction

Monotonic Stack Introduction

A monotonic stack is a stack that maintains elements in either strictly increasing or strictly decreasing order.

Types

  1. Monotonic Decreasing: Top is smallest element
  2. Monotonic Increasing: Top is largest element

Why It Works

When we encounter an element that violates the monotonic property, we pop elements and process them. Each element is pushed and popped at most once.

Time Complexity

O(n) - each element is pushed and popped at most once.

When to Use

  • Next greater element
  • Next smaller element
  • Largest rectangle in histogram
  • Daily temperatures
  • Stock span problem

Monotonic Stack Problems

Monotonic Stack Problems

1. Next Greater Element (LeetCode 496)

public int[] nextGreaterElement(int[] nums1, int[] nums2) {
    Map<Integer, Integer> map = new HashMap<>();
    Deque<Integer> stack = new ArrayDeque<>();
    
    for (int num : nums2) {
        while (!stack.isEmpty() && stack.peek() < num) {
            map.put(stack.pop(), num);
        }
        stack.push(num);
    }
    
    int[] result = new int[nums1.length];
    for (int i = 0; i < nums1.length; i++) {
        result[i] = map.getOrDefault(nums1[i], -1);
    }
    return result;
}
// Time: O(n), Space: O(n)

2. Daily Temperatures (LeetCode 739)

public int[] dailyTemperatures(int[] temperatures) {
    int n = temperatures.length;
    int[] result = new int[n];
    Deque<Integer> stack = new ArrayDeque<>();
    
    for (int i = 0; i < n; i++) {
        while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
            int prevIndex = stack.pop();
            result[prevIndex] = i - prevIndex;
        }
        stack.push(i);
    }
    return result;
}
// Time: O(n), Space: O(n)

3. Largest Rectangle in Histogram (LeetCode 84)

public int largestRectangleArea(int[] heights) {
    Deque<Integer> stack = new ArrayDeque<>();
    int maxArea = 0;
    int n = heights.length;
    
    for (int i = 0; i <= n; i++) {
        int currentHeight = (i == n) ? 0 : heights[i];
        while (!stack.isEmpty() && heights[stack.peek()] > currentHeight) {
            int height = heights[stack.pop()];
            int width = stack.isEmpty() ? i : i - stack.peek() - 1;
            maxArea = Math.max(maxArea, height * width);
        }
        stack.push(i);
    }
    return maxArea;
}

Template

// Next Greater Element (Decreasing Stack)
for (int i = 0; i < n; i++) {
    while (!stack.isEmpty() && arr[stack.peek()] < arr[i]) {
        int index = stack.pop();
        result[index] = i;  // or arr[i]
    }
    stack.push(i);
}

// Next Smaller Element (Increasing Stack)
for (int i = 0; i < n; i++) {
    while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) {
        int index = stack.pop();
        result[index] = i;  // or arr[i]
    }
    stack.push(i);
}

Practice Problems

0/3solved
Daily Temperatures
Monotonic Stack

Given an array of temperatures, return an array answer where answer[i] is the number of days you have to wait to get a warmer temperature.

Example:

Input: temperatures = [73,74,75,71,69,72,76,73]

Output: [1,1,4,2,1,1,0,0]

Wait 1 day for 74, 4 days for 76, etc.

Optimal Solution — O(n) time, O(n) space

Monotonic decreasing stack

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int[] result = new int[n];
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
                int prev = stack.pop();
                result[prev] = i - prev;
            }
            stack.push(i);
        }
        return result;
    }
}

Edge Cases:

  • All same temperatures
  • Strictly increasing
  • Strictly decreasing
Next Greater Element II
Monotonic Stack - Circular

Given a circular integer array nums, return the next greater number for every element.

Example:

Input: nums = [1,2,1]

Output: [2,-1,2]

Circular array: next greater of last element is 2.

Optimal Solution — O(n) time, O(n) space

Monotonic stack with circular traversal

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int n = nums.length;
        int[] result = new int[n];
        Arrays.fill(result, -1);
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i = 0; i < 2 * n; i++) {
            while (!stack.isEmpty() && nums[stack.peek()] < nums[i % n]) {
                result[stack.pop()] = nums[i % n];
            }
            if (i < n) stack.push(i);
        }
        return result;
    }
}

Edge Cases:

  • Single element
  • All same
  • No next greater
Online Stock Span
Monotonic Stack - Design

Design a StockSpanner class that calculates the span of stock prices. The span is the maximum number of consecutive days for which the price was less than or equal to today's price.

Example:

Input: StockSpanner s = new StockSpanner(); s.next(100); s.next(80); s.next(60); s.next(70); s.next(60); s.next(75); s.next(85);

Output: [1,1,1,2,1,4,6]

Span of 85 is 6 (days 75,60,70,60,80,100 <= 85).

Optimal Solution — Amortized O(1) time, O(n) space

Monotonic stack storing prices and spans

class StockSpanner {
    Deque<int[]> stack; // [price, span]
    
    public StockSpanner() {
        stack = new ArrayDeque<>();
    }
    
    public int next(int price) {
        int span = 1;
        while (!stack.isEmpty() && stack.peek()[0] <= price) {
            span += stack.pop()[1];
        }
        stack.push(new int[]{price, span});
        return span;
    }
}

Edge Cases:

  • Strictly increasing
  • Strictly decreasing
  • All same price

Quiz

1. What is the time complexity of monotonic stack solutions?

Question 1 options

2. For next greater element, which stack direction do we use?

Question 2 options

3. What is the primary purpose of Monotonic Stack?

Question 3 options

4. What is a common mistake when implementing Monotonic Stack?

Question 4 options

Flashcards

Question

What is a monotonic stack?

Answer

A stack that maintains elements in strictly increasing or decreasing order.

Question

When to use monotonic stack?

Answer

For next greater/smaller element problems, and histogram problems.

Question

What is Monotonic Stack?

Answer

Monotonic Stack is a key concept in software engineering.

Question

When to use Monotonic Stack?

Answer

Use Monotonic Stack when building production systems that require reliability, scalability, and maintainability.

Question

Monotonic Stack best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1.Monotonic stack maintains order
  • 2.Each element processed exactly once
  • 3.Use for next greater/smaller problems
  • 4.Template pattern is reusable

Interview Tips

  • Identify if problem needs next greater/smaller
  • Draw the stack evolution
  • Explain why O(n) is optimal

Cheat Sheet

Monotonic Stack Cheat Sheet

Decreasing Stack: For next greater element
Increasing Stack: For next smaller element
Time: O(n) - each element pushed/popped once
Pattern: Pop while condition violated, push current