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