week5 D 滑動視窗 單調佇列

2021-10-04 05:54:16 字數 1514 閱讀 6566

給定乙個陣列(大小為n),以及乙個視窗(大小為k)。視窗在陣列上從開始到結尾移動,輸出每個位置的視窗裡的最大值和最小值。

如圖:

兩行數字,第一行兩個數字,分別為陣列的大小和視窗的大小,其中1<=k<=n<=1000000。

輸出有兩行。第一行輸出滑動視窗在從左到右的每個位置時,滑動視窗中的最小值。第二行是最大值。

一、可以暴力,依次找出每個串列埠中的最大值和最小值,但會超時。

二、單調佇列,用單調遞增佇列找出每個視窗的最小值,用單調遞減佇列找到每個視窗的最大值。以找最小值為例,首先初始化佇列,即先將第乙個視窗內的值按要求加入佇列中去。即當前要加入的數的值如果大於等於佇列尾部的值,則直接入佇列。否則隊尾指標tail–,直到隊列為空或者可以大於隊尾的值的時候,將其入佇列。初始化後,佇列第乙個數即第乙個視窗的最小的值。其後定義視窗左端點和右端點l,r。在每一輪迴圈中,l++,r++,即視窗移動乙個位置。在移動中r對應的數即為要入佇列的數,其操作與初始化佇列的操作相同。但要判斷當前的隊首的元素是否在當前的的視窗內,即top如果在當前的佇列外,隊首出佇列,即top++。在視窗每移動一次,便可得到乙個當前視窗的最小值。當r到達最右端的n時,迴圈結束。得到每乙個視窗的最小值。最大值得實現與此相同。最後輸出即可。

#include

#include

using

namespace std;

int a[

1000010];

int qu[

1000010];

int top=0;

int tail=0;

intmain()

tail=

1,top=1;

qu[tail]=1

;//初始化佇列

for(

int i=

2; i<=k; i++

) tail++

; qu[tail]

=i;}

cout<

]<<

" ";

int l=

1,r=k;

while

(rtail++

; qu[tail]

=r;

cout<

]<<

" ";

} cout<

tail=

1,top=1;

qu[1]

=1;for

(int i=

2; i<=k; i++

) tail++

; qu[tail]

=i;}

cout<

]<<

" ";

l=1,r=k;

while

(rtail++

; qu[tail]

=r; cout<

]<<

" ";

}return0;

}

Week5 D 滑動視窗(單調佇列)

問題描述 現有乙個長度為n的數列和乙個大小為k的視窗 1 k n 1000000 視窗可以在數列上來回移動。現在要求出在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少。準備知識 單調佇列 單調 佇列 可執行操作 以單調遞增隊列為例 1.隊尾入隊 如果隊列為空或者隊尾元素小於入隊元素,則...

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.解題思路 區域性最大最小可利用單調佇列,以單調遞增隊列為...