給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為; 針對陣列的滑動視窗有以下6個: , , , , , 。
解:使用雙向佇列可以滿足要求,滑動視窗的最大值總是儲存在佇列首部,佇列裡面的資料總是從大到小排列。當遇到比當前滑動視窗最大值更大的值時,則將佇列清空,並將新的最大值插入到佇列中。如果遇到的值比當前最大值小,則直接插入到佇列尾部。每次移動的時候需要判斷當前的最大值是否在有效範圍,如果不在,則需要將其從佇列中刪除。由於每個元素最多進隊和出隊各一次,因此該演算法時間複雜度為o(n)。
用雙端佇列deque儲存可能成為滑動視窗中最大元素的下標,進出佇列規則如下:
如果deque為空,直接將下標i放入deque中。
如果當前下標i-隊頭元素==w,彈出隊頭元素。
如果deque不為空,取出deque隊尾的下標j,如果arr[j]>=arr[i],將下標i放入deque隊尾。否則依次彈出隊尾元素,直到arr[j]vectormaxinwindows(const vector&num,unsigned int size)
{ vectorres;
if(num.size()dq;
//處理前size個資料,因為這個時候不需要輸出最大值
for(int i=0;inum[dq.back()]){
cout<<"dq.back:"<知識點:
1、先來講一下佇列的基本用法:
佇列是一種特殊的線性表,是一種先進先出(fifo)的資料結構。它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。
佇列的成員函式:
q.empty()
判斷佇列q是否為空,當佇列q空時,返回true;否則為false(值為0(false)/1(true))。
q.size()
訪問佇列q中的元素個數。不可寫成sizeof(q)或size(q)
q.push()
會將乙個元素a置入佇列q中
q.front()
返回佇列q內的第乙個元素(也就是第乙個被置入的元素)。(不可寫成front(q))
q.back()
會返回佇列q中最後乙個元素(也就是最後被插入的元素)。(不可寫成back(q))
q.pop()
會從佇列q中移除第乙個元素。(不可寫成pop(q))
2、雙端佇列 deque
deque容器為乙個給定型別的元素進行線性處理,像向量一樣,它能夠快速地隨機訪問任乙個元素,並且能夠高效地插入和刪除容器的尾部元素。但它又與vector不同,deque支援高效插入和刪除容器的頭部元素,因此也叫做雙端佇列。
可以用鐵軌來比喻雙端佇列。
劍指offer刷題 補充01 滑動視窗的最大值
題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 注 滑動視窗的更新維護 思路 本題的關鍵在於實現視窗最大值的更新。陣列arr長度為n,視窗大小為w,則一共產生n ...
劍指offer 滑動視窗問題
給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 本人思路 每次滑動,總是減去乙個值,新增乙個值 如果新增值大於上乙個視窗的最大值,那麼新增值為本視窗的最大值 否則,如果上乙...
劍指offer刷題
面試題6 從尾到頭列印鍊錶 struct listnode class solution reverse res.begin res.end return res 替換空格class solution int newnumstr numstr numspace 2 if newnumstr leng...