滑動視窗取最小值
思想:1.滑動視窗是乙個陣列的長度為k的一部分;
2.建立雙端佇列,該佇列有序,隊頭元素最小;
3.什麼時候進佇列:
如果當前元素比隊尾元素大,或者隊列為空,直接進隊;
如果當前元素比隊尾元素小,則隊尾元素出隊,直至當前元素大於隊尾元素或者隊列為空,元素進隊。
4.什麼時候出隊:
取每個視窗對應的最小值的時候,保證隊頭元素在視窗裡面;
隊頭出列時,判斷隊頭元素是否在視窗裡面,如果在則直接輸出;
否則,則一直出隊頭元素,直至所出的隊頭元素在視窗裡面,然後輸出。
5.佇列中存的是什麼:元素下標,節省空間;
6.單調佇列,在末端插入,彈出,首端只彈出,不插入。隊首始終為最小值。
7.如果新入隊的元素與隊頭元素的距離》=滑動視窗的寬度,則隊頭元素出佇列。
*/
#include #include #include #include using namespace std;
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
const int maxn=1000000+5;
int a[maxn],q1[maxn],q2[maxn];//q1、q2儲存下標,元素的值可以通過訪問下標間接訪問到;
int head1,tail1,head2,tail2,index1,index2,k,n;
//q1為遞減佇列陣列,對應的是頭,尾分別為 head1,tail1
//q2為遞增佇列陣列,對應的是頭,尾分別為 head2,tail2
//k為滑動視窗的長度;
//n為序列總的 長度;
inline void enqueue(int cur)//維護插入操作,單調遞減佇列;
inline void enqueue(int cur)//單調遞增佇列;
inline void dequeue(int cur)
inline void dequeue(int cur)
int main()
printf("\n");
rep(i,1,k-1)//維護佇列1,隊首元素最大;
enqueue(i);
rep(i,k,n)
printf("\n");
}return 0;
}/*結果:
8 31 3 -1 -3 5 3 6 7
-1 -3 -3 -3 3 3
3 3 5 5 6 7
*/
滑動視窗的最大值 雙端佇列
題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 思路 使用暴力求解方法,複雜度為o nk 想到之前使用棧求最小值的演算法,但是棧只能一段刪除資料,所以使用兩端佇列...
lintcode 滑動視窗的最大值 雙端佇列
給出乙個可能包含重複的整數陣列,和乙個大小為 k 的滑動視窗,從左到右在陣列中滑動這個視窗,找到陣列中每個視窗內的最大值。給出陣列 1,2,7,7,8 滑動視窗大小為k 3.返回 7,7,8 解釋 最開始,視窗的狀態如下 1,2 7 7 8 最大值為7 然後視窗向右移動一位 1,2,7,7 8 最大...
lintcode 滑動視窗的最大值 雙端佇列
給出乙個可能包含重複的整數陣列,和乙個大小為 k 的滑動視窗,從左到右在陣列中滑動這個視窗,找到陣列中每個視窗內的最大值。給出陣列 1,2,7,7,8 滑動視窗大小為k 3.返回 7,7,8 解釋 最開始,視窗的狀態如下 1,2 7 7 8 最大值為7 然後視窗向右移動一位 1,2,7,7 8 最大...