Monotonic Stack Fundamentals: Solving Next Greater Element Problems

Core Concept

The monotonic stack is a powerful technique for solving next greater elemant problems efficiently. The key insight is to maintain a stack that keeps candidate elements in a specific order, allowing us to find the next greater element for each position in a single pass.

Fundamental Example

Problem: Given an array, find the next greater element for each position. If no greater element exists to the right, return -1.

Input: [2, 5, 9, 3, 1, 12, 6, 8, 7]

Output: [5, 9, 12, 12, 12, -1, 8, -1, -1]

The algorithm processes the array from right to left while maintaining a monotonic decreasing stack. When encountering a new element, we pop smaller elements from the stack since they can never serve as the next greater element for any position to the left.

function findNextGreaterElements(arr) {
  const result = new Array(arr.length).fill(-1);
  const monoStack = [];
  
  for (let i = arr.length - 1; i >= 0; i--) {
    while (monoStack.length > 0 && arr[i] >= monoStack[monoStack.length - 1]) {
      monoStack.pop();
    }
    result[i] = monoStack.length > 0 ? monoStack[monoStack.length - 1] : -1;
    monoStack.push(arr[i]);
  }
  
  return result;
}

const input = [2, 5, 9, 3, 1, 12, 6, 8, 7];
console.log(findNextGreaterElements(input));

LeetCode 739: Daily Temperatures

Given an array of daily temperatures, return how many days until a warmer temperature arrives. If no warmer day exists, use 0.

function getDaysUntilWarmer(temps) {
  const days = new Array(temps.length).fill(0);
  const indexStack = [];
  
  for (let i = temps.length - 1; i >= 0; i--) {
    while (indexStack.length > 0 && temps[i] >= temps[indexStack[indexStack.length - 1]]) {
      indexStack.pop();
    }
    days[i] = indexStack.length > 0 ? indexStack[indexStack.length - 1] - i : 0;
    indexStack.push(i);
  }
  
  return days;
}

LeetCode 496: Next Greater Element I

Given two arrays where nums1 is a subset of nums2, find the next greater element for each element in nums1 within nums2.

The approach involves first computing the next greater element for every value in nums2, then using a hash map to retrieve results for nums1 elements.

function findNextGreater(nums1, nums2) {
  const answer = new Array(nums1.length).fill(-1);
  const valueToNext = new Map();
  const tempStack = [];
  
  for (let i = nums2.length - 1; i >= 0; i--) {
    while (tempStack.length > 0 && nums2[i] >= tempStack[tempStack.length - 1]) {
      tempStack.pop();
    }
    valueToNext.set(nums2[i], tempStack.length > 0 ? tempStack[tempStack.length - 1] : -1);
    tempStack.push(nums2[i]);
  }
  
  for (let j = 0; j < nums1.length; j++) {
    answer[j] = valueToNext.get(nums1[j]);
  }
  
  return answer;
}

Key Takeaways

The monotonic stack pattern excels at O(n) solutions for next greater element problems. The stack maintains potential candidates while we iterate through the array, and we always pop elements that are smaller than or equal to the current element. This ensures each element enters and leaves the stack at most once, yielding linear time complexity.

Tags: monotonic-stack stack array next-greater-element algorithms

Posted on Mon, 01 Jun 2026 17:08:05 +0000 by MadTechie