單調棧與佇列的應用
阿新 • • 發佈:2022-01-14
1、單調棧一般是求數列某個數最左側第一個大於或小於這個數的數
題目如下:
程式碼如下:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 10; int stk[N], top; int n; int main() { cin >> n; while (n -- ) { int x; scanf("%d", &x); while(top && stk[top] >= x) top --; //棧不空且大於這個數的話,則彈出 if(top) printf("%d ", stk[top]); //棧不空的話,棧頂則是小於它的第一個數。 else printf("-1 "); stk[++ top] = x; //壓棧 } }
2、單調佇列的典型應用,滑動視窗
題目如下:
程式碼如下:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e6+10; int a[N], q[N]; int hh, tt = -1; int main() { int n, k; cin >> n >> k; for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]); for (int i = 0; i < n; i ++ ) { if(hh <= tt && q[hh] < i- k + 1) hh ++; /*如果隊頭(佇列存的是陣列下標,q[hh] 代表隊頭是陣列的第幾個數字)已經出了視窗,則用hh++的方式讓隊頭始終在窗口裡*/ while(hh <= tt && a[q[tt]] >= a[i]) tt --; /*如果佇列不空,而且隊尾元素大於當前新進佇列元素,則移除隊尾元素,使佇列單調 */ q[++ tt] = i; if(i >= k - 1)printf("%d ",a[q[hh]]); } puts(""); tt = -1, hh = 0; // 勿忘記清空佇列 for (int i = 0; i < n; i ++ ) { if(hh <= tt && q[hh] < i- k + 1) hh ++; /*如果隊頭(佇列存的是陣列下標,q[hh] 代表隊頭是陣列的第幾個數字)已經出了視窗,則用hh++的方式讓隊頭始終在窗口裡*/ while(hh <= tt && a[q[tt]] <= a[i]) tt --; /*同理*/ q[++ tt] = i; if(i >= k - 1)printf("%d ",a[q[hh]]); } }
3、總結
牢記單調棧與佇列的應用。
本文來自部落格園,作者:Medjay,轉載請註明原文連結:https://www.cnblogs.com/Medjay/p/15805038.html