視窗:可以理解為一段連續子陣列,下標範圍為(l,r]
滑動視窗:l、r會改變,改變方式是右移,r會右移,l也會右移,但始終保持l滑動視窗的最大值/最小值更新結構:對某乙個陣列,初始時,l、r均位於最左端,l、r只可以向右移,且始終有l以陣列arr = 為例解釋滑動視窗最大值更新結構維護的過程,使用【】來表示滑動視窗的範圍
該更新結構為雙端佇列,雙端結構中存放陣列的下標,且存放時保證按順序存放的下標中的數遞減
具體流程如下所示:
【】9 3 10 1 7 7
此時滑動視窗中沒有值,雙端隊列為空
r右移
2. 3 10 1 7 7
r右移一位,此時滑動視窗出現了乙個數為9,於是將9的下標從隊尾入隊
此時的雙端隊列為 [ 0->9 ] (為方便觀察,將下標指向的數也寫在這裡)
3. 【9 3】 10 1 7 7
r右移一位,3進入滑動視窗,3小於隊尾0位置處的9,將3的下標從隊尾入隊
此時的雙端隊列為 [ 0->9 , 1->3 ]
4. 【9 3 10】 1 7 7
r右移一位,10進入滑動視窗,10大於隊尾1位置處的3,將隊尾出隊
再比較發現10仍然大於隊尾0位置處的9,將隊尾出隊,此時,雙端隊列為空了,將10的下標入隊
此時的雙端隊列為 [ 2->10 ]
5. 【9 3 10 1】 7 7
r右移一位,1進入滑動視窗,此時的情況與步驟3相似,直接將1的下標入隊
此時的雙端隊列為 [ 2->10 ,3->1 ]
6. 【9 3 10 1 7】 7
r右移一位,7進入滑動視窗,7大於隊尾3位置處的1,將隊尾出隊
再比較發現7小於隊尾2位置處的10,將7的下標入隊
此時的雙端隊列為 [ 2->10 ,4->7 ]
l右移
7. 9【 3 10 1 7】 7
將當前移出滑動視窗數字的下標(過期的下標)與雙端佇列隊首的下標比較,如果過期的下標與隊首下標相等,則將隊首出隊,因為隊首已經不在滑動視窗內了,否則,不做任何處理
此時的雙端佇列仍然為 [ 2->10 ,4->7 ]
8. 9 3 【10 1 7】 7
此時的雙端佇列仍然為 [ 2->10 ,4->7 ]
9. 9 3 10 【 1 7】 7
l右移一位後下標2過期,將隊首出隊
此時的雙端隊列為 [ 4->7 ]
最大值
當前滑動視窗的最大值就是雙端佇列的隊首下標資料
將雙端佇列中的資料理解為:在當前滑動視窗下,該下標處資料為最大值的可能性
由於l、r都只能右移,所以,如果當前新加入滑動視窗的資料比隊尾元素大,那麼隊尾元素不可能再成為滑動視窗的最大值,如果當前新加入的滑動視窗的資料比隊尾元素小,那麼當前新加入的元素可能在隊尾元素過期後成為滑動視窗的最大值。
因此,我們可以考慮,當當前新加入滑動視窗的資料與隊尾元素相等,應該如何操作?
答案是將隊尾元素出隊,然後將當前元素的下標入隊,因為當前元素一定比隊尾元素晚過期
10. 9 3 10 【 1 7 7 】
此時的雙端佇列然為 [ 4->7 ]
要得到滑動視窗最小值更新結構,可以將雙端佇列中存放資料的規則改為遞增排列
1)給定乙個陣列num,對陣列中長度為m的所有連續子陣列,存在乙個最大值,求這些最大值中的最小值
這是今年秋招時,我遇到的華為第一輪面試的手撕**題,現在回頭看,發現是乙個典型的滑動視窗問題。
思路:構造乙個初始長度為m的滑動視窗更新結構,將l和r同時右移,可以很容易得到所有的長度為m的連續子陣列以及這些連續子陣列的最大值
int findminofmax(vector&v, int m)
mqueue2.push_back(r);
} else //r到達末尾,可以直接根據當前視窗情況輸出所有結果
; retvv.push_back(tempv);
}l++;
}break;
} maxvalue = v[mqueue1.front()];
minvalue = v[mqueue2.front()];
while (maxvalue - minvalue > n )
;retvv.push_back(tempv);
}l++;
if (l < r)
else break;
}} return retvv;
}
如有疏漏,請指正。 視窗以及視窗內最大值或最小值的更新結構
什麼是視窗?假設現在有一陣列及兩個指標l和r,兩指標只能在陣列上向右移動且不能回退,那麼 l r 這個區域即是乙個視窗。假設現在有一需求,即在視窗滑動的過程中我們需要求視窗內的最大值。這時我們需求借助最大值的更新結構,即雙端佇列。該更新結構需要保持其中的元素從大到小 從左到右 排序。加數過程 指標r...
求滑動視窗中的最大值和最小值
滑動視窗 一般使用雙指標演算法,左指標l和右指標r之間的空間稱為視窗,由於指標是不斷移動的,從而視窗也可以移動,稱為滑動視窗。滑動視窗的最值 由於視窗是移動的,移動的過程中有新元素的加入也有舊元素的彈出。每一次元素的加入或彈出都可能使視窗中元素的最值發生變化,也正是會發生變化,使得無法直接獲取任意時...
滑動視窗求解最大 最小值問題
結論 求最大值時使用雙端對維護遞減資料,即佇列中資料依次遞減,佇列頭部資料始終為最大值,每次將遍歷到的資料與佇列尾部的資料進行比較 如果不違反佇列的遞減規律 遍歷到的資料元素小於佇列尾部資料 就直接插入佇列尾部 如果違反了佇列的遞減規律就依次從佇列尾部彈出資料,直到找到能夠保持佇列遞減規律的位置。求...