單調棧

單調棧,就是一個棧,不過棧內元素保證單調性。即,棧內元素要麼從小到大,要麼從大到小。
而單調棧維護的就是一個數前/後第一個大於/小於他的數。數組

例題:P5788 【模板】單調棧
例題就是一個求每一個數後第一個大於他的數。spa

那麼重點來了:怎麼作!面對這樣的數據,很差下手。那麼咱們把她轉化一下:有\(n\)我的,每一個人向右看,求她看到的第一我的。
看圖:

經過觀察,咱們會發現,在她後面的,比她矮的,必定會被她遮住。那麼,這個點就沒用了。而根據現實生活和剛纔的推斷,咱們看到的人確定是一個比一個高的,而沒看到的,留着也沒用,直接扔了QwQ。那麼,這就是符合單調性的。再看,那些沒用的人何時扔掉?固然是遇到比她高的人了。那麼就能夠一個一個地走掉,並且確定是在已經判斷過的人的前面(中間和後面的在以前就走掉了),因此就直接從前面彈出。咦?這不就像一個棧嗎?沒錯,這就是單調棧的實現方法。code

再概括一下:blog

  • 從後往前掃get

  • 對於每一個點:io

    • 彈出棧頂比她小的元素
    • 此時棧頂就是答案
    • 加入這個元素

因爲是從前日後輸出,還要把答案放到一個數組裏。模板

放代碼:class

#include<cstdio>
#include<stack>
using namespace std;
int n,a[3000005],f[3000005];//a是須要判斷的數組(即輸入的數組),f是存儲答案的數組
stack<int>s;//模擬用的棧
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=n;i>=1;i--)
	{
		while(!s.empty()&&a[s.top()]<=a[i]) s.pop();//彈出棧頂比當前數小的
		f[i]=s.empty()?0:s.top();//存儲答案,因爲沒有比她大的要輸出0,因此加了個三目運算
		s.push(i);//壓入當前元素
	}
	for(int i=1;i<=n;i++) printf("%d ",f[i]);//輸出
	return 0;
}

完 結 辣!方法

相關文章
相關標籤/搜索