zoukankan      html  css  js  c++  java
  • 单调栈算法 入门+博客推荐+模板

    单调栈算法 入门+博客推荐+模板

    博客推荐

    用法及作用:https://www.cnblogs.com/lher/p/7620330.html

    简介

    首先需要明确定义:1.单调递增的栈,2.单调递减的栈

    1. 单调递增的栈:从栈顶到栈底是递增的,每次压进去的数要小于栈顶元素,输出也是单调递增的,主要是解决最大值的区间问题;
    2. 单调递减的栈:从栈顶到栈底是递减的,每次压进去的数要大于栈顶元素,输出也是单调递减的,主要是解决最小值的区间问题;

    这里的单调性是否严格,要根据实际情况来做决定。

    在一个数列中,单调栈解决的是以某个值为最小(最大)值的最大区间,也就是我们需要知道当以这个值为最小值时,在这个数列中的左右区间是什么。

    模板

    //求最小值时的区间,使用单调递减栈
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<stack>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    const double esp=1e-6;
    const int inf=0x3f3f3f3f;
    const int MAXN=1E5+7;
    ll num[MAXN], st[MAXN];
    int n, top, lt[MAXN], rt[MAXN];
    int main()
    {
        //这里是求正数数列的
    	while(scanf("%d",&n) && n!=0)
    	{
    		top=0; st[top]=0; //预处理
    		num[0]=-1; num[n+1]=-1;//预处理,因为输入的数都是正数,所以这个是最小的数
    		for(int i=1; i<=n; i++)
    			scanf("%lld", &num[i]);
    		for(int i=1; i<=n+1; i++)//这里多一个是为了全部输出
    		{
    			lt[i]=i;
    			rt[i]=i;
    			while(num[st[top]] > num[i]) //栈顶元素大于要进栈的数
    			{
                 	rt[st[top]] = i-1;
    				lt[i] = lt[st[top]];
    				top--;	 
    			}
    			if(num[st[top]] == num[i]) lt[i] = lt[st[top]];//很重要的,很巧妙的代码
    			st[++top]=i;//大于等于栈顶的数进栈。
    		}
    		for(int i=1; i<=n; i++)
    			printf("%d %d
    ", lt[i], rt[i]);
    	}
    	return 0;
    }
    
    //求最大值时的区间,使用单调递增栈,小于等于栈顶的数进栈
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<stack>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    const double esp=1e-6;
    const int inf=0x3f3f3f3f;
    const int MAXN=1E5+7;
    ll num[MAXN], st[MAXN];
    int n, top, lt[MAXN], rt[MAXN];
    int main()
    {
        while(scanf("%d",&n) &&n!=0)
        {
            top=0; st[top]=0;
            num[0]=-1; num[n+1]=-1;
        	for(int i=1; i<=n; i++)
                scanf("%d", &num[i]);
            for(int i=1; i<=n+1; i++)
            {
                lt[i]=i;
                rt[i]=i;
                while(num[st[top]] < num[i])
                {
                    rt[st[top]]=i-1;
                    lt[i]=lt[st[top]];
                    top--;
                }
                if(num[st[top]] == num[i])
                    lt[i] = lt[st[top]];
                st[++top]=i;
    		}
            for(int i=1; i<=n; i++)
                print("%d %d
    ", lt[i], rt[i]);
    	}
        return 0;
    }
    
  • 相关阅读:
    UltraWebGrid多表头
    2009个人年度总结报告(IT)
    DevExpress分发
    AspxTreeList数据绑定以及模板和外观定制的运用
    每日一句英语:No problem, Mr. Smith. Anything else?
    “向程序发送命令时出现问题”的解决方法
    ASP常用进制转化类(2,8,10,16,32,64)
    我的分页用户控件(性能问题)
    研发的那些事2—设计之惑
    一个架构的演化2用ESB集成
  • 原文地址:https://www.cnblogs.com/alking1001/p/12299121.html
Copyright © 2011-2022 走看看