单调栈【完整思路+代码】

单调栈【完整思路+代码】_第1张图片
看到这道题,首先我们会想到的肯定是暴力模拟。外层循环i是每个数,内层循环j是从i-1到最开头,找第一个比i小的数。这样做的话,如果数据是10的5次方,那么双重循环时间是非常可怕的。

然后我们来分析一下上面这个思路,看看有哪里可以优化。因为找的肯定是比他小且最接近的数,那么如果第2个数比第一个数小,对于第三个数来说第一个数肯定是没用的(因为第二个距离第三个数更近),而且对于第四个第五个以至于第n个数都是这样。你可以仔细想想,所以对于第一个数和第二个数,我们只需要存起来第二个数就可以了,以此类推,如果第三个数比第二个数小,对于第四个到第n个数来说第二个数就成了没用数,就只需要保存第三个数。那么什么情况下是有用数呢?我们再举个栗子,如果第二个数比第一个数大,那么我们两个数就都要存下来,因为你不知道第三个数是否比第二个数大。也就是说,你需要存储的数列是一个单调递增的序列。这就是单调栈的原理。

代码如下:

#include
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);}
	}
}	

你可能感兴趣的:(数据结构)