C 單調佇列入門應用 例題詳解 滑動視窗

2021-09-02 22:37:09 字數 1373 閱讀 5800

滑動視窗

關於這道題,首先會想到暴搜,但資料太大,絕對超時。用暴搜的思路來說,就是乙個乙個列舉,再在當中找出最大最小值,會發現,每次都在重複列舉,那有沒有什麼方法可以儲存之前的值?

這就引出主題了——單調佇列

單調佇列,就是乙個佇列,但有單調性,就是佇列裡的元素是遞增或遞減的

例如    1 2 3 4 5 6 7 8 9 就是乙個單調佇列,每個元素都比之前的大

那單調佇列與滑動視窗有什麼關係

首先要建立兩個雙向佇列,乙個求最大,乙個求最小,接下來就是主要思想

a[i].num表數值,a[i].id表位址,先把第乙個元素放進去,然後依次放入後面的元素,在放每個元素之前,得先做乙個維護

一. 保證隊頭為最大值

二. 保持單調性(就保持其遞增或遞減)

三. 位址小於視窗前端的不入隊

先遍歷一遍佇列,把位址小於視窗前端的pop掉

那先拿需要放入的元素與隊內元素比較,比它小的,pop出去,直到有元素比它大為止,若都比它小,就全踢完,每次迴圈過後輸出最大最小值,這樣就能保證每個元素都只會進隊出隊一次,時間複雜度就為o(n)。

結合**,理解一下

#include #include #include #define n 1000005

#define ll long long

using namespace std;

int n , k ;

ll maxn[n] , minn[n] ;

struct que a[n];

deque z;//求min

deque q;//求max

int main()

z.push_back(a[1]);

q.push_back(a[1]);

minn[1] = a[1].num;

maxn[1] = a[1].num;

for(int i = 2 ; i <= n ; i ++ )

printf("%lld",minn[k]);

for(int i = k + 1 ; i <= n ; i ++ )

printf(" %lld" , minn[i]);

putchar('\n');

printf("%lld",maxn[k]);

for(int i = k + 1; i <= n ; i ++ )

printf(" %lld", maxn[i]);

putchar('\n');

return 0;

}

本人也為萌新,歡迎一起交流討論

滑動視窗 單調佇列入門題

給定乙個大小為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 ...

滑動視窗 單調佇列入門題

給定乙個大小為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 ...

單調佇列 入門

今天寫了人生中第乙個單調佇列,激動ing 先看一道單調佇列的入門題 乙個含有n項的數列 n 2000000 求出每一項前面的第m個數到它這個區間內的最小值。先寫出動規方程 f i min j合法 很明顯的,這是乙個n 2的動規,但是,我們可以注意到,數列中有些數無論如何都不會被選到.如 1 2 8 ...