Skip to main content

Monotonic Stack in Data Structures and Algorithms

In this tutorial, we will delve into the concept of a monotonic stack in Data Structures and Algorithms. We'll explore what a monotonic stack is, how it works, and its applications.

Monotonic Stack in Data Structures and Algorithms​

A monotonic stack, also known as a monotone stack or an increasing/decreasing stack, is a variation of the stack data structure that maintains either monotonic increasing or monotonic decreasing order of its elements.

Characteristics​

  • Monotonicity: The key characteristic of a monotonic stack is that the elements are either monotonically increasing or monotonically decreasing.
  • Single Direction: Unlike a regular stack, where elements can be pushed and popped in any order, a monotonic stack enforces a single direction of monotonicity.
  • Optimization: Monotonic stacks are often used to optimize certain problems by efficiently identifying elements that are greater (or smaller) than the current element.

monotonic stack

Operations​

A monotonic stack typically supports the following operations:

  • Push: Adds an element to the stack while maintaining monotonicity.
  • Pop: Removes and returns the top element of the stack.
  • Peek: Returns the top element of the stack without removing it.
  • isEmpty: Checks if the stack is empty.
  • Size: Returns the number of elements in the stack.

Applications​

Monotonic stacks find applications in various algorithms and problems, including but not limited to:

  • Finding Next Greater/Smaller Element: Monotonic stacks can efficiently find the next greater or smaller element for each element in an array.
  • Largest Rectangle in Histogram: They are used to solve the problem of finding the largest rectangle in a histogram efficiently.
  • Finding the Nearest Smaller Element: Monotonic stacks can determine the nearest smaller element for each element in an array.
  • Maximal Rectangles in Binary Matrix: Used in algorithms to find the maximal rectangles in a binary matrix.

Now, let's see an example implementation of a monotonic stack in various programming languages.

function monotonicStack(arr) {
const stack = [];
const result = [];

for (let i = 0; i < arr.length; i++) {
while (stack.length && arr[i] < arr[stack[stack.length - 1]]) {
result[stack.pop()] = arr[i];
}
stack.push(i);
}

while (stack.length) {
result[stack.pop()] = -1;
}

return result;
}

// Example usage
const arr = [2, 1, 4, 3, 6, 5, 8, 7];
const nextSmallerElements = monotonicStack(arr);
console.log("Next Smaller Elements:", nextSmallerElements);

Conclusion​

In this tutorial, we explored the concept of a monotonic stack in Data Structures and Algorithms. We discussed its characteristics, operations, and applications. Additionally, we provided example implementations of a monotonic stack in JavaScript, Python, TypeScript, C++, and Java. Monotonic stacks offer a powerful tool for solving various algorithmic problems efficiently by maintaining monotonicity of elements.