什么是单调栈?
从名字上就听的出来,单调栈中存放的数据应该是有序的,所以单调栈也分为单调递增栈和单调递减栈
- 单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小
- 单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大
单调栈的伪代码
stack<int> st;
//此处一般需要给数组最后添加结束标志符,具体下面例题会有详细讲解
for (遍历这个数组)
{
if (栈空 || 栈顶元素大于等于当前比较元素)
{
入栈;
}
else
{
while (栈不为空 && 栈顶元素小于当前元素)//单调增栈
{
栈顶元素出栈;
更新结果;
}
当前数据入栈;
}
}
具体实践:
题目1:132 模式
给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。
如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [3,1,4,2]
输出:true
解释:序列中有 1 个 132 模式的子序列: [1, 4, 2] 。
代码设计:
//时间复杂度为O(n*n)
import java.util.*;
class Solution {
public boolean find132pattern(int[] nums) {
//建立一个栈 采用时间复杂度为O(n*n)
int l=nums.length;
int index=0;
while(index<l){
Stack<Integer>s=new Stack();
for(int j=index+1;j<l;j++){//其实index下标在不断改变
if(nums[j]>nums[index]&&s.size()==0)
s.add(nums[j]);//加入一个元素
if(s.size()==1&&nums[j]>s.peek())//使得中间的元素尽可能的大
{
s.pop();
s.add(nums[j]);
}
if(nums[j]>nums[index]&&s.size()==1&&nums[j]<s.peek())
return true;//判断条件
}
index++;
}
return false;
}
}
单调栈解法:
public boolean find132pattern(int[] nums) {
int len=nums.length;
if(len<3) return false;
Stack<Integer> st=new Stack<>();
int K=-1;
for(int I=len-1;I>=0;I--){//从后往前扫描
if(K>-1&&nums[K]>nums[I]) return true;//判断是否可以
while(!st.isEmpty()&&nums[st.peek()]<nums[I]){
K=st.pop();//单调增栈 从顶到底 依次递增
}
st.push(I);//比栈顶小 插入
}
return false;
}