Welcome to the next lesson in our module on linear data structures. In our last session, we explored the queue and its First-In, First-Out (FIFO) nature, applying it to manage a sliding time window. Today, we return to the stack, but with a twist. We'll be exploring a powerful and elegant pattern known as the monotonic stack.
This technique is a favorite in coding interviews because it provides a highly efficient, linear-time solution to a class of problems that seem to require a slower, quadratic approach at first glance. Mastering this pattern will significantly enhance your ability to solve complex array-based problems. Specifically, by the end of this lesson, you will be able to apply the monotonic stack to solve the classic "Next Greater Element" problem and its variations.
The Monotonic Stack: An Ordered Approach
So, what exactly is a monotonic stack? As the name suggests, it's a stack that maintains a strict order among its elements. The elements, from the bottom of the stack to the top, are always sorted, either in a non-increasing (decreasing) or non-decreasing (increasing) fashion.
The core idea is to use this ordered property to efficiently find relationships between elements in a sequence, such as the "next greater element" or "previous smaller element." By processing an array in a single pass and using the stack to keep track of elements "waiting" for their match, we can achieve an optimal time complexity of . This is because each element is pushed onto the stack exactly once and popped at most once.
The following article provides a concise introduction to this concept.
This reading from Hello Interview defines what a monotonic stack is and immediately frames it with the "Next Greater Element" problem, which will be our focus.
Read the introductory section, starting from the definition down to the problem description. This will give you the formal definition and a concrete example of what we're trying to solve.
Solving "Next Greater Element"
The "Next Greater Element" problem is the canonical example for demonstrating the power of a monotonic stack. The problem statement is as follows:
Given an array of integers, find the next greater element for each element. The next greater element of
xis the first element to its right that is greater thanx. If no such element exists, the answer is -1.
For example, given [2, 1, 3, 2, 4, 3], the output should be [3, 3, 4, 4, -1, -1]. A brute-force approach would use nested loops, taking time. We can do much better.
The Algorithm
We will use a monotonically decreasing stack. The stack won't store the numbers themselves, but rather their indices. This is a crucial detail, as it allows us to easily update the corresponding position in our result array.
Here's the plan:
- Initialize a
resultarray of the same size as the input, filled with-1. This handles the case where no greater element is found. - Initialize an empty
stack. - Iterate through the input array from left to right, with index
iand valuecurrent_num. - For each
current_num, we look at the top of the stack. While the stack is not empty andcurrent_numis greater than the number at the index on top of the stack, we have found the "next greater element" for the element corresponding to the index on top of the stack.- We
popthe index from the stack. - We use this popped index to place
current_numinto ourresultarray. - We repeat this until the stack is empty or the condition is no longer met.
- We
- After the
whileloop finishes, wepushthe current indexionto the stack.
This process ensures that the values corresponding to the indices in the stack are always in decreasing order. When we encounter a new number, it "resolves" all the smaller numbers on the stack that were waiting for their next greater element.
The image below shows the initial state for solving this problem. We have our input array, a result array initialized to -1, and an empty stack ready to store indices.

The next image demonstrates the core logic in action. At "step 3," the current element is 3. The top of the stack holds the index for the value 1. Since 3 > 1, we know 3 is the next greater element for 1. We would pop the index for 1 and update our result.

The NeetCode video below provides an excellent walkthrough of this entire process, including the Python implementation.
Next Greater Element I - Leetcode 496 - Python
This video walks through the "Next Greater Element I" problem, explaining the monotonic stack approach from the ground up.
Watch from the beginning to the problem explanation to understand the brute-force method and why we need a more optimal approach. The core logic is explained from this segment, where the monotonic stack is introduced and the algorithm is visualized. Finally, watch the coding part to see how this translates into a clean Python solution. Pay attention to how a hash map is used to handle the specific constraints of the "Next Greater Element I" variant on LeetCode. The fundamental monotonic stack logic remains the same.
To solidify this, let's look at the implementation for the general version of the problem (finding the next greater element for all items in a single array).
This part of the Hello Interview article provides the Python code and a clear, step-by-step explanation of the algorithm we just discussed.
First, read the Initialization section. Then, carefully study the Iteration and Processing sections. The key takeaway is in this sentence: "Popping all the elements that are smaller than nums[i] from the stack before pushing i ensures that the stack stays monotonically decreasing."
The final Python code looks like this:
def nextGreaterElement(nums):
n = len(nums)
result = [-1] * n # Initialize result with -1
stack = [] # This will store indices
for i in range(n):
# While stack is not empty AND current element is greater than
# the element at the index on top of the stack
while stack and nums[i] > nums[stack[-1]]:
# We found the next greater element for the index on top of the stack
index = stack.pop()
result[index] = nums[i]
# Push current index onto the stack
stack.append(i)
return result
# Example
print(nextGreaterElement([2, 1, 3, 2, 4, 3]))
# Output: [3, 3, 4, 4, -1, -1]
Applying the Pattern: Daily Temperatures
Once you understand the "Next Greater Element" pattern, you can solve a variety of related interview problems. A classic example is "Daily Temperatures" (LeetCode 739).
The problem asks: Given an array of daily temperatures, return an array where each element is the number of days you have to wait until a warmer temperature. If there is no future day for which this is possible, put 0.
This is just a slight variation of "Next Greater Element". Instead of storing the value of the next greater element, we need to store the distance between the indices. The logic remains identical.
The following video provides a fantastic explanation.
Daily Temperatures - Monotonic Stack - Leetcode 739 - Python
This NeetCode video solves the "Daily Temperatures" problem using the same monotonic stack pattern.
First, watch the problem overview to see how it relates to what we've just learned. Next, the intuition section explains exactly why a monotonically decreasing stack is the perfect tool here. Follow the step-by-step simulation to see the stack and result array evolve. Finally, review the Python code implementation. Note the critical line where the result is calculated: result[stack_index] = i - stack_index. This is the only major change from the NGE problem.
Conclusion
In this lesson, you've added a sophisticated and efficient pattern to your algorithmic toolkit. The monotonic stack is a prime example of how choosing the right data structure can transform a slow algorithm into a highly optimized one.
Key Takeaways:
- A monotonic stack is a stack that maintains its elements in a sorted (non-increasing or non-decreasing) order.
- It is the go-to pattern for finding the "next/previous greater/smaller element" in a sequence, achieving this in time and space.
- The core mechanism involves a
whileloop that pops elements from the stack whenever a new element from the input array would violate the monotonic property, resolving the search for those popped elements. - Storing indices on the stack, rather than values, is often the key to solving these problems, as it allows you to calculate distances or update a result array at the correct position.
In our next lesson, we will continue our exploration of specialized stacks by learning how to design and implement a Min Stack. This data structure supports all standard stack operations, plus an additional getMin operation that returns the minimum element in the stack in constant time.