問題描述:
現有乙個長度為n的數列和乙個大小為k的視窗(1<=k<=n<=1000000),視窗可以在數列上來回移動。現在要求出在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少。
準備知識:
單調佇列:單調+佇列
可執行操作:(以單調遞增隊列為例)
1.隊尾入隊:如果隊列為空或者隊尾元素小於入隊元素,則隊尾入隊。
2.隊尾出隊:在隊尾入隊過程中,如果不滿足1入隊會破壞隊內元素的單調性,則需要將不滿足條件的隊尾元素全部隊尾出隊後,將入隊元素入隊。
3.隊首出隊:當隊尾元素和隊首元素的序列號之差大於區域性視窗時,隊首出隊,以維護區域性單調性。
功能:由於單調佇列可以隊首出隊以及前面的元素一定比後面的元素先入隊的性質,使得它可以維護區域性單調性。
解題思路:
1.維護乙個單調佇列,佇列中的元素均屬於當前視窗,隊首即為當前視窗的最小值或最大值。
2.注意最開始入隊的k-1個元素,會輸出k-1個隊首值,但應該丟棄,因為此時並未達到乙個視窗數量,應該從第k個入隊元素開始記錄隊首。
**實現:
#include
#include
using
namespace std;
int a[
1000050];
int q[
1000050];
int minans[
1000000];
int maxans[
1000000];
int maxsize =0;
int minsize =0;
intmain()
int l =
1, r =0;
for(
int i =
1; i <= n; i++
) l =
1,r =0;
for(
int i =
1; i <= n; i++
)for
(int i=k-
1;i) cout
int i=k-
1;i)}
總結:與單調棧一樣,不太理解原理,只知道手算模擬,確實是隊首元素即為當前視窗最值。也要注意佇列中儲存的是序列號! week5 D 滑動視窗 單調佇列
給定乙個陣列 大小為n 以及乙個視窗 大小為k 視窗在陣列上從開始到結尾移動,輸出每個位置的視窗裡的最大值和最小值。如圖 兩行數字,第一行兩個數字,分別為陣列的大小和視窗的大小,其中1 k n 1000000。輸出有兩行。第一行輸出滑動視窗在從左到右的每個位置時,滑動視窗中的最小值。第二行是最大值。...
WEEK 5 D 滑動視窗
zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 輸入有兩行。第一行兩個整數n和k分別表示數列的長度和滑動視窗的大小,1 k n 1000000。第二行有n個整數表示zjm的數...
Week5 D 滑動視窗
問題描述 zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 數列是 1 3 1 3 5 3 6 7 其中 k 等於 3.解題思路 區域性最大最小可利用單調佇列,以單調遞增隊列為...