單調佇列 滑動視窗

2022-05-16 17:36:08 字數 1354 閱讀 2131

題目鏈結

給定乙個大小為n≤10

6'>n≤106n≤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

思路:首先想暴力的做法,時間複雜度是o(n*k),然後再來看是否可以優化的地方。以輸視窗最小值為例:可以發現,在乙個視窗中,如果來了乙個小的數,那麼比此數大的數就永遠不會成為最小值了,所以我們在入隊的時候,需要把此數前面比他大的數全部出隊,聯想一下,每次入隊後,每個元素的左邊都會比他小,

因為比他大的都出隊了。所以可見,這會形成乙個單調遞增的佇列,所以每滑動一次視窗,只需要輸出隊頭就行了,隊頭就是最小的。還有一點值的說的是,佇列裡只需要存放乙個元素時,只需要存放此元素在原陣列中的下標。

#include using

namespace

std;

typedef

long

long

ll;const

int maxn = 1e6+10

;int

n,k;

int a[maxn]; //

原陣列

int q[maxn]; //

儲存元素的下標

void

up()

cout

<}void down()

cout

<} int

main()

單調佇列 滑動視窗

nkoj 2152 description 給你乙個長度為n n 10 6 的陣列,乙個長為k的滑動的窗體從最左移至最右端,你只能見到視窗的k個數,每次窗體向右移動一位,找出窗體所包含的數字的最大和最小值,如下表所示 k的值為3 視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 ...

滑動視窗 單調佇列

給定乙個大小為n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 3 1 3 5 3...

單調佇列 滑動視窗

p1886 滑動視窗 模板 單調佇列 有乙個長為 n 的序列 a,以及乙個大小為 k 的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。如果按照暴力方法做的話,每一次判斷相鄰的k個數的最大值和最小值,複雜度為o n k 肯定會超時,因此就想到把每次的最大值和...