Sliding Window 單調佇列解決--經典滑動視窗問題--求視窗的最大值最小值
阿新 • • 發佈:2019-01-02
這就要用到單調遞減或單調遞增佇列來實現,它的頭元素一直是佇列中的最小值或最大值。我們可以從佇列的末尾插入一個元素,可以從佇列的兩端刪除元素。
插入元素:
對於單調遞減佇列:隊頭放最大值,為了保持佇列的遞減性,我們在插入元素v的時候,要將隊尾元素與v比較,如果隊尾<v,則刪除隊尾元素,然後繼續將新的隊尾元素與v比較,直到隊尾元素>v,這時才將v插入隊尾。
刪除隊首元素:
隊尾元素的刪除剛剛已經說了,那麼隊首的元素什麼時候刪除呢?當隊首元素的索引或下標小於i-k+1的時候,說明隊首元素已經沒用了,因為他已經不在窗裡了,所以當隊首元素索引或下標<i-k+1時,將隊首元素刪除。
#include<iostream> #include<cstdio> #include<deque> using namespace std; const int maxn=1e6+6; struct node { int val,id; }; int minn[maxn],maxx[maxn],a[maxn]; int main() { int n,k,i; node now; deque<node>qmin; deque<node>qmax; scanf("%d%d",&n,&k); scanf("%d",&now.val); now.id=1; a[1]=now.val; minn[1]=now.val; qmin.push_back(now); for(i=2;i<=n;i++) { scanf("%d",&a[i]); now.val=a[i]; now.id=i; while(!qmin.empty()&&qmin.back().val>a[i]) qmin.pop_back(); qmin.push_back(now); if(!qmin.empty()&&qmin.front().id<i-k+1) qmin.pop_front(); minn[i]=qmin.front().val; } maxx[1]=a[1]; now.val=a[1]; now.id=1; qmax.push_back(now); for(i=2;i<=n;i++) { now.val=a[i]; now.id=i; while(!qmax.empty()&&qmax.back().val<a[i]) qmax.pop_back(); qmax.push_back(now); if(!qmax.empty()&&qmax.front().id<i-k+1) qmax.pop_front(); maxx[i]=qmax.front().val; } for(i=k;i<n;i++) printf("%d ",minn[i]); printf("%d\n",minn[n]); for(i=k;i<n;i++) printf("%d ",maxx[i]); printf("%d\n",maxx[n]); }