单调栈是一种数据结构,主要用O(n)解决NGE问题(Next Greater Element),就是找到当前序列中,上一个或者下一个比它大或比它小的元素。
解题思路:判断当前元素和栈顶元素的大小,来决定是否让栈顶元素出栈,当前元素进栈作为新的栈顶。
典型例题:
思路:题中说nums1是nums2的子集,我们就可以对应nums2来建一个hashmap,最后通过nums1里的值来找到map对应键的值。map里的值放的是当前元素有没有下一个更大元素。
倒着遍历放入栈中,这样先放入的元素一定是没有下一个更大元素,然后就可以以此类推。遇到比栈顶大的就pop掉,把当前元素放入栈,成为栈顶。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
//存放结果的数组
int num[] = new int[nums1.length];
//栈,单调栈
Stack<Integer> a = new Stack<>();
//键放nums2的值,值是下一个值有没有比当前值大
Map<Integer,Integer> map = new HashMap<>();
for(int i=nums2.length-1;i>=0;i--) {
while(!a.empty()&&a.peek()<nums2[i]){
a.pop(); //将小数出栈
}
//表示如果当前栈为空就表示将要压入的数是目前最大的,不为空就表示,此数不是最大的,找上一个
map.put(nums2[i],a.empty()?-1:a.peek());
a.push(nums2[i]); //将大数入栈
}
for(int i=0;i<num.length;i++){
//根据键找值赋给num[i]
num[i]=map.get(nums1[i]);
}
return num;
}
}
思路:定一个中间值,逆序遍历放入栈,比较当前值和栈顶元素大小,如果当前元素大于栈顶元素,说明找到了3,此时把2赋值给中间值,然后下次循环时,如果发现当前元素小于中间值。则说明找到132模式的子序列。
class Solution {
public boolean find132pattern(int[] nums) {
if(nums.length<=2) return false;
Stack<Integer> num = new Stack<>();
//定义中间值
int numsk = Integer.MIN_VALUE;
//逆序找
for(int i=nums.length-1;i>=0;i--){
//定义当前值
int cur = nums[i];
//找到当前的三
while(!num.isEmpty()&&cur>num.peek()){
//把二拿出并且赋给中间值
numsk = Math.max(numsk,num.pop());
}
//把当前的三放进去
num.push(cur);
//判断元素值和2的大小关系
if(numsk>cur){
return true;
}
}
return false;
}
}