单调栈

什么是单调栈?
从名字上就听的出来,单调栈中存放的数据应该是有序的,所以单调栈也分为单调递增栈和单调递减栈

  • 单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小
  • 单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大

单调栈的伪代码

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
解释:序列中有 1132 模式的子序列: [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;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值