給定乙個大小為n≤10
6'>n≤106
n≤106的陣列。
有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。
您只能在視窗中看到k個數字。
每次滑動視窗向右移動乙個位置。
以下是乙個例子:
該陣列為[1 3 -1 -3 5 3 6 7],k為3。
視窗位置
最小值最大值
[1 3 -1] -3 5 3 6 7-13
1 [3 -1 -3] 5 3 6 7-33
1 3 [-1 -3 5] 3 6 7-35
1 3 -1 [-3 5 3] 6 7-35
1 3 -1 -3 [5 3 6] 736
1 3 -1 -3 5 [3 6 7]37
您的任務是確定滑動視窗位於每個位置時,視窗中的最大值和最小值。
輸入格式
輸入包含兩行。
第一行包含兩個整數n和k,分別代表陣列長度和滑動視窗的長度。
第二行有n個整數,代表陣列的具體數值。
同行資料之間用空格隔開。
輸出格式
輸出包含兩個。
第一行輸出,從左至右,每個位置滑動視窗中的最小值。
第二行輸出,從左至右,每個位置滑動視窗中的最大值。
輸入樣例:
8 3
1 3 -1 -3 5 3 6 7
輸出樣例:
-1 -3 -3 -3 3 3
3 3 5 5 6 7
這題我們可以使用陣列模擬佇列來進行求解,每次對queue維護,我們對這串數從左到右遍歷,想象乙個長度為k的視窗在上面不斷的向右滑動~
而在這個視窗中(以最小值為例),我們每次入隊乙個數,如果有ai>aj && i我個人認為這段**最難理解的是:當視窗劃過時,如何去更新queue,可以這樣理解,queue中的首項永遠是我們視窗裡面最小值的位置,如果我們遍歷i的時候找到了比queue首項位置上更小的數,就將這個數的位置,更新成queue的首項,否則就一直在queue的隊尾加數,而當我當前遍歷到的位置i,i-k+1>q[hh],也就是說在極限情況時,q[hh]是視窗左邊框,i是視窗的右邊框,就需要將h++來維護佇列.
具體操作:
1 3 -1 -3 5 3 6 7
第一步:將 1 入隊,hh=0,q[0]=0;
第二步:1<3,將 3 入隊, hh=0 ,q[0]=0,q[1]=1;
第三步:3>-1, 前面的數都出隊,將 -1 入隊, hh=0, q[0]=2, 輸出a[2]=-1;
第四步:-1>-3, 前面的數都出隊, 將-3入隊,hh=0, q[0]=3, 輸出a[3]=-3;
第五步:-3<5, 將 5 入隊, hh=0, q[0]=3,q[1]=4, 輸出a[3]=-3;
第六步:5>3, 將5出隊, 3入隊,hh=0, q[0]=3, q[1]=5, 輸出a[3]=-3;
第七步:3<6,將6入隊,此時i-k+1=4,hh++,hh=1,q[1]=5,q[2]=6, 輸出a[5]=3;
第八步:6<7,將7入隊, hh=1,hh=1,q[1]=5,q[2]=6,輸出3;
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
const
int n=1e6+10
;using
namespace
std;
typedef pair
pii;
intn,k;
inta[n],q[n];
intmain()
return0;
}
Acwing 154 滑動視窗 單調佇列
這題和poj2823是一樣的 解析 暴力,直接對於每k個都遍歷一遍,很顯然複雜度o nk 的話行不通。對於這類問題,有乙個比較一致的思路,就是有些數字是無用的,或者用了幾次後就要被扔掉的,後續根本就排不上用場。比如有ai,aj,ax,ax ai aj,找ax左邊第乙個比它小的數,很明顯,ai壓根不需...
AcWing 154 滑動視窗(模板)
給定乙個大小為n 10 6 n 106 n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。視窗位置 最小值最大值 1 3 1 3 5 3 6 7 13 ...
AcWing 154 滑動視窗(C 演算法)
有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。您的任務是確定滑動視窗位於每個位置時,視窗中的最大值和最小值。輸入格式 輸入包含兩行。第一行包含兩個整數n和k,分別代表...