問題描述:
zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗, 視窗可以在數列上來回移動. 現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少. 例如:
數列是 [1 3 -1 -3 5 3 6 7], 其中 k 等於 3.
解題思路:
區域性最大最小可利用單調佇列,以單調遞增隊列為例,隊首即為最小值,從左到右a[i]依次入佇列:先看隊首索引是否滿足條件,如果i-front>k-1,刪除隊首元素,若隊尾元素比a[i]大,則彈出隊尾元素,該區間內的最小值即為隊首,當i>k-2時將隊首元素記錄下來即可。
!!note:
要注意視窗k=1時的處理,因為如果k=1,a[0]是沒有被記錄的,以至於後面無法輸出minarr[0]
input:
輸入有兩行。第一行兩個整數n和k分別表示數列的長度和滑動視窗的大小,1<=k<=n<=1000000。第二行有n個整數表示zjm的數列。
output:
輸出有兩行。第一行輸出滑動視窗在從左到右的每個位置時,滑動視窗中的最小值。第二行是最大值。
sample input:
8 3
1 3 -1 -3 5 3 6 7
sample output:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
實驗**:
#include
#include
using
namespace std;
long
long
int minarr[
1000100];
//儲存滑動視窗的最小值
long
long
int maxarr[
1000100];
//儲存滑動視窗的最大值
long
long
int a[
1000100];
//儲存陣列元素值
struct pairck};
void
huad
(int n,
int k)
p1.index=i;
p1.value=a[i]
; q1.
push_back
(p1)
; mine=q1.
front()
.value;
p2=q2.
front()
;if(i-p2.index>k-1)
q2.pop_front()
;while
(!q2.
empty()
&&q2.
back()
.value
) p2.index=i;
p2.value=a[i]
; q2.
push_back
(p2)
; maxe=q2.
front()
.value;
if(i>k-2)
}if(k==1)
for(
int i=k-
1;i) cout<
for(
int i=k-
1;i) cout<
}int
main
(void
)
WEEK 5 D 滑動視窗
zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 輸入有兩行。第一行兩個整數n和k分別表示數列的長度和滑動視窗的大小,1 k n 1000000。第二行有n個整數表示zjm的數...
Week5 D 滑動視窗滑動視窗
week5 d 滑動視窗滑動視窗 zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 數列是 1 3 1 3 5 3 6 7 其中 k 等於 3.window position ...
week5 D 滑動視窗滑動視窗
zjm 有乙個長度為 n 的數列和乙個大小為 k 的視窗,視窗可以在數列上來回移動.現在 zjm 想知道在視窗從左往右滑的時候,每次視窗內數的最大值和最小值分別是多少.例如 數列是 1 3 1 3 5 3 6 7 其中 k 等於 3.window position minimum value max...