乙個單調遞增棧的例子:
進棧元素分別為3,4,2,6,4,5,2,3
第i步操作結果1
3進棧3
23出棧,4進棧43
2進棧4 2
42、4出棧,6進棧65
4進棧6 4
64出棧,5進棧
6 57
2進棧6 5 2
82出棧,3進棧
6 5 3
對於乙個元素i: **
//在「尾部」新增元素
while
(r !=
0|| ms[r]
<= x) r--
;ms[
++r]
= x;
//查詢棧頂元素
if(r !=0)
printf
("%d\n"
, ms[r]);
else
printf
("-1"
);
這裡可以把x換成元素x得下標壓入棧
乙個遞增單調佇列的例子
佇列大小不能超過3,入隊元素依次為3,2,8,4,5,7,6,4
第i步操作結果1
3入隊3
23從隊尾出隊,2入隊23
8入隊2 8
48從隊尾出隊,4入隊
2 45
5入隊2 4 5
62從隊頭出隊,7入隊
4 5 7
77從隊尾出隊,6入隊
4 5 6
86、5、4從隊尾出隊,4入隊4
**
//在「尾部」新增元素x
while
(l != r && mq[r]
<= x) r--
;mq[
++r]
= x;
//查詢隊首元素
if(l != r)
printf
("%d\n"
, mq[l+1]
);else
printf
("-1\n");
//彈出隊首元素
if(l != r) l++
;
下面直接見練習題(持續收集)
poj 2823
**題意:**就是給你n 和 k,表示元素的個數, 以及區間長度, 要求輸出從1到n-k為起始下標的每個長度為k的區間的最小值輸出,以及最大值輸出。
**題解:**這裡用單調佇列寫,記錄的是下標,並且判斷一下當前的最值的下標在不在當前的區間內就可,具體看**。
**:
//#include
#include
#include
using namespace std;
const
int maxn =
1e6+50;
int n, len, l, r;
int a[maxn]
;int mq[maxn]
;int
main()
///1 3 -1 -3 5 3 6 7
///3 2 8 4 5 7 6 4
l =0, r =0;
for(
int i =
1; i <= n; i++
) mq[r++
]= i;
while
(mq[l]
<= i - len) l++
;//for(int j = l; j < r; j++)
// cout << a[mq[j]] << " ";
//cout << endl;
if(i >= len) cout << a[mq[l]
]<<
" ";
} cout << endl;
l =0, r =0;
for(
int i =
1; i <= n; i++
) cout << endl;
return0;
}
poj 3250
**題意:**給你n頭奶牛的高度,從左到右依次排列,都向右看,現在要你求每一頭奶牛向右看可以看到的奶牛總數。
**題解:**單調佇列簡單題
**:
#include
#include
using namespace std;
const
int maxn =
1e6+60;
long
long n, a[maxn]
;long
long h[maxn]
, w[maxn]
, cur =0;
long
long ans =0;
const
int inf =
0x3f3f3f3f
;void
solve()
else
h[++cur]
= a[i]
; w[cur]
= cur-1;
}if(cur ==0)
return;}
}int
main()
單調棧,單調佇列
大多數借鑑了 單調佇列是什麼呢?可以直接從問題開始來展開。poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106,m n 我們知道,解法 在暴力列舉的過程中,有乙個地方是重複比較了,就是在找當前的f i 的時候,i的前面其它m 1個數在算f i 1 ...
單調棧 單調佇列
單調棧 單調佇列是在棧和佇列的基礎上加上單調結構的資料結構。如果乙個元素入棧或入隊,他會檢查之前的元素,如果之前的元素不可能是答案的解,那麼就彈出元素,使得當前元素入棧或入隊。leetcode 239 滑動視窗最大值 此題是單調佇列,每次遇到乙個元素,一直從隊尾彈出,直到隊尾元素大於該元素為止。還需...
單調棧 單調佇列
啊學完了來寫個總結吧 顧名思義,單調,就是指色彩單一某乙個容器裡面的元素都是遞增或遞減的,而單調棧和單調佇列就是這個容器。單調棧 單調棧模板 其他的我就不說了,講下為什麼單調棧是從後往前掃瞄 當我們在判斷乙個數後面第乙個比它大的數時,前提是後面的數已經被處理了,所以我們要從後往前掃瞄。我做了兩種做法...