Code Templates
Monotonic Stack
Use Cases
Use Case | Description | Example |
---|---|---|
Next Greater Element | Given an array of integers, find the next greater element for each element in the array. If there is no greater element, return -1. | For the array [2, 1, 2, 4, 3] , the next greater elements are [4, 2, 4, -1, -1] . |
Next Smaller Element | Given an array of integers, find the next smaller element for each element in the array. If there is no smaller element, return -1. | For the array [4, 5, 2, 10, 8] , the next smaller elements are [2, 2, -1, 8, -1] . |
Code Template
Initializes variables
result = [-1] * n
: Creates a list of the same length as nums, initialized to -1. This will hold the next greater elements.stack = []
: Initializes an empty list to track indices of elements in nums during iteration.
Check for next greater element
- Checks if the
stack
is not empty and if the current elementnums[i]
is greater than the element at the index on the top of the stack. - If both conditions are true, it means
nums[i]
is the next greater element for the index at the top of thestack
, and we pop indices from thestack
until this condition is false.
Append current index to stack
- Retrieves the
index
from thestack
and updates the result list with the current elementnums[i]
as its next greater element. - Adds the current index
i
to thestack
for future comparisons.
def next_greater_elements(nums):n = len(nums)result = [-1] * nstack = []
Common mistakes
- Wrong Stack Comparison Direction
# Wrong:while stack and nums[stack[-1]] > nums[i]: # Finds next smaller element# Correct:while stack and nums[stack[-1]] < nums[i]: # Finds next greater element
- Wrong Stack Content Storage
# Wrong: storing values instead of indicesstack.append(nums[i]) # Can't track original positionsresult[stack.pop()] = nums[i] # Will cause error# Correct:stack.append(i) # Store indices to track positionsindex = stack.pop()result[index] = nums[i]
- Wrong Result Array Initialization
# Wrong: using empty list or zerosresult = [] # Can't index into empty listresult = [0] * n # Can't distinguish between actual 0 and no answer# Correct:result = [-1] * n # Use -1 to indicate no greater element found
- Wrong Stack Empty Check
# Wrong: missing stack checkwhile nums[stack[-1]] < nums[i]: # Will error on empty stack# Wrong: wrong order of conditionswhile nums[stack[-1]] < nums[i] and stack: # Will error# Correct:while stack and nums[stack[-1]] < nums[i]: # Check stack first
Related Problem
class Solution:def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:n = len(nums2)result = {} # map number to its next greater elementstack = []# Find next greater element for each number in nums2for i in range(n):while stack and nums2[stack[-1]] < nums2[i]:index = stack.pop()result[nums2[index]] = nums2[i]stack.append(i)# Build result for nums1 using the mappingreturn [result.get(x, -1) for x in nums1]
class Solution:def dailyTemperatures(self, temperatures: List[int]) -> List[int]:n = len(temperatures)result = [0] * nstack = []for i in range(n):while stack and temperatures[stack[-1]] < temperatures[i]:index = stack.pop()result[index] = i - indexstack.append(i)return result
class StockSpanner:def __init__(self):self.stack = [] # (price, span) pairsdef next(self, price: int) -> int:span = 1while self.stack and self.stack[-1][0] <= price:prev_price, prev_span = self.stack.pop()span += prev_spanself.stack.append((price, span))return span
1019. Next Greater Node In Linked List
class Solution:def nextLargerNodes(self, head: Optional[ListNode]) -> List[int]:# Convert linked list to arraynums = []while head:nums.append(head.val)head = head.nextn = len(nums)result = [0] * nstack = [] # (index, value) pairsfor i in range(n):while stack and stack[-1][1] < nums[i]:prev_idx, _ = stack.pop()result[prev_idx] = nums[i]stack.append((i, nums[i]))return result