Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A monotonic stack turns repeated searches for the next greater or smaller neighbor into a linear-time scan. It also finds the largest rectangle in a histogram by locating the first shorter bar on each side of every candidate bar. The key is to store unresolved array indices and choose a comparison rule that matches the problem’s definition of “greater” or “smaller.”

What a monotonic stack does

A monotonic stack is a stack whose candidate values remain in sorted order as the scan progresses. In array problems, store indices rather than just values: an index gives you the value, position, and distance needed to build the answer.

For next-greater-to-the-right, keep indices in decreasing value order. The stack holds elements whose answer has not yet appeared. When a new value is greater than the value at the top index, it is the first qualifying value to the right for that index, so pop the index and record the answer. Repeat until the stack is empty or its top is no longer smaller, then push the new index. This is the core pattern described in CrackAlgo’s monotonic-stack explanation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find the next greater element to the right

For a strictly greater answer, compare with <: equal values do not resolve one another. Initialize answers to the problem’s no-answer marker, then scan left to right:

answer = [-1] * n
stack = []  # indices whose next-greater answer is unresolved

for i in range(n):
    while stack and values[stack[-1]] < values[i]:
        j = stack.pop()
        answer[j] = values[i]
    stack.append(i)

Any indices still in the stack at the end have no strictly greater value to their right, so their answers remain -1. If the problem allows an equal value to qualify, change the comparison deliberately; using <= resolves equal values as well.

#1 Best Overall
Sale
Cracking the Coding Interview: 189 Programming Questions and Solutions
  • Careercup, Easy To Read
  • Condition : Good
  • Compact for travelling

Why the nested loop is still linear

Although each scan step contains a while loop, each index is pushed once and popped at most once. Across the entire input there are at most n pushes and n pops, so the total work is O(n), not O(n²) repeated forward searches.

Return a distance instead of a value

In Daily Temperatures, the next warmer day resolves an earlier day in the same way, but the output is the wait in days. When index j is popped at index i, store i - j rather than values[i]. The underlying unresolved-index pattern is unchanged.

Handle a circular array

For a circular next-greater problem, scan a logical doubled array so indices near the end can find a greater value near the beginning. Push each original index only during the first traversal; the second traversal supplies wraparound candidates without adding duplicate indices to the stack. The template approach is documented in the neetcode monotonic-stack templates.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find the largest rectangle in a histogram

For a bar of height h to be the limiting height of a rectangle, the rectangle can extend until the first strictly shorter bar on either side. If those boundaries are at indices left and right, the usable width is right - left - 1, and the area is h × width. This boundary interpretation is the basis of the histogram method described in the Masst monotonic stack documentation.

Maintain an increasing stack of bar indices. When the current bar is shorter than the bar at the top, the current index is the right boundary for the popped bar. After popping, the new top is its left boundary; if there is no new top, use -1. The candidate area is then calculated for the popped bar.

max_area = 0
stack = []  # indices of bars in increasing height order

for right in range(len(heights) + 1):
    current = heights[right] if right < len(heights) else 0

    while stack and heights[stack[-1]] > current:
        j = stack.pop()
        left = stack[-1] if stack else -1
        width = right - left - 1
        max_area = max(max_area, heights[j] * width)

    if right < len(heights):
        stack.append(right)

The extra iteration uses a virtual height of zero to drain pending bars. This version pops only when the current height is strictly smaller, so equal-height indices can remain together. A version that pops on smaller-or-equal heights can also work, provided its boundary and width handling are consistent.

Walk through a histogram

For [2, 1, 5, 6, 2, 3], the maximum rectangle has height 5 across the adjacent bars 5 and 6, for an area of 10. When the height-2 bar arrives, it pops the height-6 bar: the left boundary is the height-5 bar, the width is 1, and the area is 6. It then pops the height-5 bar: the left boundary is the height-1 bar, the right boundary is the new height-2 bar, and the width is 2, producing area 10.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recognize when the pattern applies

Look for questions about the nearest greater or smaller item on one side, or about a range that ends at the first item that breaks a height or value condition. The stack is useful when advancing the scan can permanently resolve some candidates; it is not a general-purpose speed-up for every array problem.

  • Next Greater Element I: map each value to its next greater value.
  • Next Greater Element II: adapt the scan for circular wraparound.
  • Daily Temperatures: find the next warmer position and return the distance.
  • Largest Rectangle in Histogram: use nearest-shorter boundaries to calculate candidate areas.
  • Maximal Rectangle: build consecutive-one heights row by row, then run the histogram solver for each row; this extension is described in CrackAlgo’s overview.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose the invariant and comparison rule deliberately

Before coding, specify what the stack represents and what event resolves an index. These choices prevent common duplicate and boundary errors.

  • Increasing or decreasing: decide which value order preserves the candidates needed for the neighbor relation.
  • Strict or non-strict comparison: use the operator that matches whether equal values qualify. For histogram bars, handle equal heights consistently when finding boundaries.
  • Output: record a value, an index, a distance, or an area as the problem requires.
  • Traversal: use one pass for ordinary next-greater searches, a doubled logical scan for circular arrays, or repeated histogram scans for row-based extensions.
  • End handling: use a sentinel or an explicit flush so unresolved histogram candidates are measured.

The unifying idea is that a new element often settles the nearest qualifying neighbor for every candidate it causes to leave the stack. Once that invariant and the equality rule are clear, the same reasoning carries from next-greater searches to histogram boundaries.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.