看到这道题,首先我们会想到的肯定是暴力模拟。外层循环i是每个数,内层循环j是从i-1到最开头,找第一个比i小的数。这样做的话,如果数据是10的5次方,那么双重循环时间是非常可怕的。
然后我们来分析一下上面这个思路,看看有哪里可以优化。因为找的肯定是比他小且最接近的数,那么如果第2个数比第一个数小,对于第三个数来说第一个数肯定是没用的(因为第二个距离第三个数更近),而且对于第四个第五个以至于第n个数都是这样。你可以仔细想想,所以对于第一个数和第二个数,我们只需要存起来第二个数就可以了,以此类推,如果第三个数比第二个数小,对于第四个到第n个数来说第二个数就成了没用数,就只需要保存第三个数。那么什么情况下是有用数呢?我们再举个栗子,如果第二个数比第一个数大,那么我们两个数就都要存下来,因为你不知道第三个数是否比第二个数大。也就是说,你需要存储的数列是一个单调递增的序列。这就是单调栈的原理。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,x;
stack<int>s;
int main()
{
cin>>n;
while(n--)
{
cin>>x;
while(!s.empty())
if(s.top()>=x) s.pop();
else {cout<<s.top()<<" "; s.push(x);break;}
if(s.empty()) {cout<<"-1"<<" ";s.push(x);}
}
}