2021.05.22单调栈解决132模式
( 题目来源:https://leetcode-cn.com/problems/132-pattern/ )
题目描述
给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。
如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。
思路
- 考虑从右往左遍历数组。
- 要点:
(1)记录模式2
(2)维护一个单调栈,记录模式3
(3)为了找到模式1,我们只需要将新元素和模式2的数字进行比较,如果新元素比模式2还要大,那么他应该放入单调栈中。
(4)为了方便找到模式1,我们需要在遍历过程中不断更新模式2,使其尽可能大。而更新模式2的步骤就是(3)中的更新单调栈操作。由于单调找中存的都是历史的模式3,所以如果新进入的元素比原始单调栈总的元素大,那么被挤出去的模式3数将更新模式2.(所谓瘦死的骆驼比马大)
代码
public boolean find132pattern(int[] nums) {
int n = nums.length;
if(n < 3) return false;
//单调栈,栈顶元素为小元素
Stack<Integer> sta = new Stack<>();
int las = Integer.MIN_VALUE;
for(int i = n-1; i >= 0; i++) {
//在模式"132"中,如果当前的数字,即1,比las的2要小,那么返回true
if(nums[i] > las) return true;
//如果新进来的比2打,即满足模式"332",那么更新2为3
while(!sta.isEmpty() && sta.peek() < nums[i]) { //如果新进入的元素比栈顶元素大,即可以将sta中记录的3模式的一个数组挤到2模式中去
las = sta.pop();
}
sta.push(nums[i]);
}
return false;
}