Before attempting this problem, you should be comfortable with:
Monotonic Stacks - The optimal solution uses a decreasing monotonic stack to efficiently track potential pattern candidates
Array Traversal Patterns - Understanding both left-to-right and right-to-left traversal strategies
Tracking Running Minimum/Maximum - Maintaining the minimum value seen so far while iterating through an array
1. Brute Force
Intuition
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.
Algorithm
Iterate k from index 2 to the end of the array.
For each k, iterate j backward from k - 1 to 1.
Skip if nums[j] <= nums[k] since we need nums[j] > nums[k].
For each valid j, iterate i backward from j - 1 to 0.
classSolution:deffind132pattern(self, nums: List[int])->bool:
n =len(nums)for k inrange(2, n):for j inrange(k -1,0,-1):if nums[j]<= nums[k]:continuefor i inrange(j -1,-1,-1):if nums[i]< nums[k]:returnTruereturnFalse
publicclassSolution{publicbooleanfind132pattern(int[] nums){int n = nums.length;for(int k =2; k < n; k++){for(int j = k -1; j >0; j--){if(nums[j]<= nums[k]){continue;}for(int i = j -1; i >=0; i--){if(nums[i]< nums[k]){returntrue;}}}}returnfalse;}}
classSolution{public:boolfind132pattern(vector<int>& nums){int n = nums.size();for(int k =2; k < n; k++){for(int j = k -1; j >0; j--){if(nums[j]<= nums[k]){continue;}for(int i = j -1; i >=0; i--){if(nums[i]< nums[k]){returntrue;}}}}returnfalse;}};
classSolution{/**
* @param {number[]} nums
* @return {boolean}
*/find132pattern(nums){let n = nums.length;for(let k =2; k < n; k++){for(let j = k -1; j >0; j--){if(nums[j]<= nums[k]){continue;}for(let i = j -1; i >=0; i--){if(nums[i]< nums[k]){returntrue;}}}}returnfalse;}}
publicclassSolution{publicboolFind132pattern(int[] nums){int n = nums.Length;for(int k =2; k < n; k++){for(int j = k -1; j >0; j--){if(nums[j]<= nums[k]){continue;}for(int i = j -1; i >=0; i--){if(nums[i]< nums[k]){returntrue;}}}}returnfalse;}}
funcfind132pattern(nums []int)bool{
n :=len(nums)for k :=2; k < n; k++{for j := k -1; j >0; j--{if nums[j]<= nums[k]{continue}for i := j -1; i >=0; i--{if nums[i]< nums[k]{returntrue}}}}returnfalse}
class Solution {funfind132pattern(nums: IntArray): Boolean {val n = nums.size
for(k in2 until n){for(j in k -1 downTo 1){if(nums[j]<= nums[k]){continue}for(i in j -1 downTo 0){if(nums[i]< nums[k]){returntrue}}}}returnfalse}}
classSolution{funcfind132pattern(_ nums:[Int])->Bool{let n = nums.count
for k in2..<n {for j instride(from: k -1, through:1, by:-1){if nums[j]<= nums[k]{continue}for i instride(from: j -1, through:0, by:-1){if nums[i]< nums[k]{returntrue}}}}returnfalse}}
Time & Space Complexity
Time complexity: O(n2)
Space complexity: O(1)
2. Stack
Intuition
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.
Algorithm
Initialize a stack to store pairs [num, minLeft] and track curMin as the running minimum.
For each element starting from index 1:
Pop elements from the stack while the current element is greater than or equal to the top.
If the stack is not empty and the current element is greater than stack.top().minLeft, return true.
Push the current element with curMin onto the stack.
Update curMin to be the minimum of itself and the current element.
We 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.
Algorithm
Initialize an empty stack and set k to negative infinity.
Iterate from the end of the array to the beginning:
If the current element is less than k, return true (we found the "1").
While the stack is not empty and the top is less than the current element:
Pop and update k to the popped value (this becomes a candidate for "2").
Push the current element onto the stack (candidate for "3").
classSolution:deffind132pattern(self, nums: List[int])->bool:
stack, k =[],float('-inf')for i inrange(len(nums)-1,-1,-1):if nums[i]< k:returnTruewhile stack and stack[-1]< nums[i]:
k = stack.pop()
stack.append(nums[i])returnFalse
publicclassSolution{publicbooleanfind132pattern(int[] nums){Stack<Integer> stack =newStack<>();int k =Integer.MIN_VALUE;for(int i = nums.length -1; i >=0; i--){if(nums[i]< k){returntrue;}while(!stack.isEmpty()&& stack.peek()< nums[i]){
k = stack.pop();}
stack.push(nums[i]);}returnfalse;}}
classSolution{public:boolfind132pattern(vector<int>& nums){
stack<int> stack;int k = INT_MIN;for(int i = nums.size()-1; i >=0; i--){if(nums[i]< k){returntrue;}while(!stack.empty()&& stack.top()< nums[i]){
k = stack.top();
stack.pop();}
stack.push(nums[i]);}returnfalse;}};
classSolution{/**
* @param {number[]} nums
* @return {boolean}
*/find132pattern(nums){const stack =[];let k =-Infinity;for(let i = nums.length -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stack.length >0&& stack[stack.length -1]< nums[i]){
k = stack.pop();}
stack.push(nums[i]);}returnfalse;}}
publicclassSolution{publicboolFind132pattern(int[] nums){Stack<int> stack =newStack<int>();int k =int.MinValue;for(int i = nums.Length -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stack.Count >0&& stack.Peek()< nums[i]){
k = stack.Pop();}
stack.Push(nums[i]);}returnfalse;}}
funcfind132pattern(nums []int)bool{
stack :=[]int{}
k := math.MinInt32
for i :=len(nums)-1; i >=0; i--{if nums[i]< k {returntrue}forlen(stack)>0&& stack[len(stack)-1]< nums[i]{
k = stack[len(stack)-1]
stack = stack[:len(stack)-1]}
stack =append(stack, nums[i])}returnfalse}
class Solution {funfind132pattern(nums: IntArray): Boolean {val stack = ArrayDeque<Int>()var k = Int.MIN_VALUE
for(i in nums.size -1 downTo 0){if(nums[i]< k){returntrue}while(stack.isNotEmpty()&& stack.last()< nums[i]){
k = stack.removeLast()}
stack.addLast(nums[i])}returnfalse}}
classSolution{funcfind132pattern(_ nums:[Int])->Bool{var stack =[Int]()var k =Int.min
for i instride(from: nums.count -1, through:0, by:-1){if nums[i]< k {returntrue}while!stack.isEmpty && stack.last!< nums[i]{
k = stack.removeLast()}
stack.append(nums[i])}returnfalse}}
Time & Space Complexity
Time complexity: O(n)
Space complexity: O(n)
4. Two Pointers
Intuition
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.
Algorithm
Initialize stkTop to n (stack starts empty) and k to negative infinity.
Iterate from the end of the array to the beginning:
If the current element is less than k, return true.
While stkTop < n and the current element is greater than nums[stkTop]:
Update k to nums[stkTop] and increment stkTop (pop from virtual stack).
Decrement stkTop and store the current element at that position (push to virtual stack).
classSolution:deffind132pattern(self, nums: List[int])->bool:
n =len(nums)
stkTop, k = n,float('-inf')for i inrange(n -1,-1,-1):if nums[i]< k:returnTruewhile stkTop < n and nums[i]> nums[stkTop]:
k = nums[stkTop]
stkTop +=1
stkTop -=1
nums[stkTop]= nums[i]returnFalse
publicclassSolution{publicbooleanfind132pattern(int[] nums){int n = nums.length;int stkTop = n;int k =Integer.MIN_VALUE;for(int i = n -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stkTop < n && nums[i]> nums[stkTop]){
k = nums[stkTop++];}
nums[--stkTop]= nums[i];}returnfalse;}}
classSolution{public:boolfind132pattern(vector<int>& nums){int n = nums.size();int stkTop = n;int k = INT_MIN;for(int i = n -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stkTop < n && nums[i]> nums[stkTop]){
k = nums[stkTop++];}
nums[--stkTop]= nums[i];}returnfalse;}};
classSolution{/**
* @param {number[]} nums
* @return {boolean}
*/find132pattern(nums){const n = nums.length;let stkTop = n;let k =-Infinity;for(let i = n -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stkTop < n && nums[i]> nums[stkTop]){
k = nums[stkTop++];}
nums[--stkTop]= nums[i];}returnfalse;}}
publicclassSolution{publicboolFind132pattern(int[] nums){int n = nums.Length;int stkTop = n;int k =int.MinValue;for(int i = n -1; i >=0; i--){if(nums[i]< k){returntrue;}while(stkTop < n && nums[i]> nums[stkTop]){
k = nums[stkTop++];}
nums[--stkTop]= nums[i];}returnfalse;}}
funcfind132pattern(nums []int)bool{
n :=len(nums)
stkTop := n
k := math.MinInt32
for i := n -1; i >=0; i--{if nums[i]< k {returntrue}for stkTop < n && nums[i]> nums[stkTop]{
k = nums[stkTop]
stkTop++}
stkTop--
nums[stkTop]= nums[i]}returnfalse}
class Solution {funfind132pattern(nums: IntArray): Boolean {val n = nums.size
var stkTop = n
var k = Int.MIN_VALUE
for(i in n -1 downTo 0){if(nums[i]< k){returntrue}while(stkTop < n && nums[i]> nums[stkTop]){
k = nums[stkTop++]}
nums[--stkTop]= nums[i]}returnfalse}}
classSolution{funcfind132pattern(_ nums:inout[Int])->Bool{let n = nums.count
var stkTop = n
var k =Int.min
for i instride(from: n -1, through:0, by:-1){if nums[i]< k {returntrue}while stkTop < n && nums[i]> nums[stkTop]{
k = nums[stkTop]
stkTop +=1}
stkTop -=1
nums[stkTop]= nums[i]}returnfalse}}
Time & Space Complexity
Time complexity: O(n)
Space complexity: O(1) extra space.
Common Pitfalls
Confusing the Pattern Order
The "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.
Using Wrong Comparison Operators
The pattern requires strict inequalities: nums[i] < nums[k] < nums[j]. Using <= instead of < will incorrectly accept patterns where two elements are equal.
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.