The most straightforward way to find a 132 pattern is to check every possible triplet. We need indices i < j < k where nums[i] < nums[k] < nums[j]. For each position k, we look backward to find a valid j (where nums[j] > nums[k]), and then look further back to find a valid i (where nums[i] < nums[k]). If all three conditions are met, we found the pattern.
k from index 2 to the end of the array.k, iterate j backward from k - 1 to 1.nums[j] <= nums[k] since we need nums[j] > nums[k].j, iterate i backward from j - 1 to 0.nums[i] < nums[k], return true.false.Instead of checking every triplet, we can use a monotonic decreasing stack to efficiently track potential j candidates along with their corresponding minimum values to the left (potential i values). As we scan from left to right, we maintain a stack of pairs [nums[j], minLeft] where minLeft is the smallest element seen before index j. When we encounter a new element, if it's greater than the minLeft of any stack entry but less than that entry's value, we found a valid 132 pattern.
[num, minLeft] and track curMin as the running minimum.stack.top().minLeft, return true.curMin onto the stack.curMin to be the minimum of itself and the current element.false if no pattern is found.class Solution:
def find132pattern(self, nums: List[int]) -> bool:
stack = [] # pair [num, minLeft], mono decreasing
curMin = nums[0]
for i in range(1, len(nums)):
while stack and nums[i] >= stack[-1][0]:
stack.pop()
if stack and nums[i] > stack[-1][1]:
return True
stack.append([nums[i], curMin])
curMin = min(curMin, nums[i])
return FalseWe can solve this more elegantly by iterating from right to left. The key insight is to track k, which represents the largest valid "2" in a potential 132 pattern (the middle value that's smaller than some "3" to its right). We use a stack to maintain elements in decreasing order. When we find an element larger than the stack top, we pop elements and update k to be the largest popped value. If we ever find an element smaller than k, we've found our "1", completing the pattern.
k to negative infinity.k, return true (we found the "1").k to the popped value (this becomes a candidate for "2").false if no pattern is found.We can achieve O(1) extra space by reusing the input array itself as a stack. The idea is the same as the optimal stack approach, but instead of using a separate stack, we use a pointer stkTop to track where our "stack" ends within the array. Elements from stkTop to n-1 form our virtual stack. This works because as we iterate from right to left, we no longer need the original values at those positions.
stkTop to n (stack starts empty) and k to negative infinity.k, return true.stkTop < n and the current element is greater than nums[stkTop]:k to nums[stkTop] and increment stkTop (pop from virtual stack).stkTop and store the current element at that position (push to virtual stack).false if no pattern is found.class Solution:
def find132pattern(self, nums: List[int]) -> bool:
n = len(nums)
stkTop, k = n, float('-inf')
for i in range(n - 1, -1, -1):
if nums[i] < k:
return True
while stkTop < n and nums[i] > nums[stkTop]:
k = nums[stkTop]
stkTop += 1
stkTop -= 1
nums[stkTop] = nums[i]
return FalseThe "132 pattern" refers to the relative ordering of values, not indices. You need nums[i] < nums[k] < nums[j] where i < j < k. A common mistake is looking for values in the wrong order or confusing which index maps to which part of the pattern name.
The pattern requires strict inequalities: nums[i] < nums[k] < nums[j]. Using <= instead of < will incorrectly accept patterns where two elements are equal.
# Wrong: allows equal values
if nums[i] <= nums[k] <= nums[j]:
# Correct: requires strict inequalities
if nums[i] < nums[k] < nums[j]:In the stack-based approach, you must track the minimum value to the left of each potential "3" (middle element). Failing to update the minimum correctly or associating it with the wrong stack element leads to missing valid patterns or false positives.