劍指 滑動視窗的最大值

2021-09-11 02:52:35 字數 1638 閱讀 7438

給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為; 針對陣列的滑動視窗有以下6個: , , , , , 。

如果採用蠻力法,這個問題似乎不難解決:可以掃瞄每乙個滑動視窗的所有數字並找出其中的最大值。如果滑動視窗的大小為 k,需要 o(k)時間才能找出滑動視窗裡的最大值。對於長度為 n 的輸入陣列,這個演算法總的時間複雜度是 o(nk)。

public class solution 

res.add(max);

}return res;

}}

實際上乙個滑動視窗可以看成是乙個佇列。當視窗滑動時,處於視窗的第乙個數字被刪除,同時在視窗的末尾新增乙個新的數字。這符合佇列的先進先出特性。如果能從佇列中找出它的最大數,這個問題也就解決了。

我們並不把滑動視窗的每個數值都存入佇列中,而只把有可能成為滑動視窗最大值的數值存入到乙個兩端開口的佇列。使用乙個單調非增佇列

,隊頭儲存當前視窗的最大值,後面儲存在視窗移動過程中導致隊頭失效(出視窗)後的從而晉公升為視窗最大值的候選值。每次新增新的數到佇列末尾時,比較最後乙個元素(當前佇列中最小值)和當前元素,如果當前元素比這個元素大,那麼最後乙個元素彈出,加入新的元素(因為最後乙個元素永遠比當前元素先出視窗,不可能成為最大元素)。如果最後一元素比當前元素大,就直接加入。向後移動過程中如果移出視窗的元素是當前最大值需要在佇列開頭移除元素。

接著以輸入數字為例一步分析。

陣列的第乙個數字是 2,把它存入佇列中。第二個數字是3.由於它比前乙個數字 2 大,因此 2不可能成為滑動視窗中的最大值。2 先從佇列裡刪除,再把3存入到佇列中。此時佇列中只有乙個數字 3。針對第三個數字 4 的步驟類似,最終在佇列中只剩下乙個數字 4。此時滑動視窗中已經有 3 個數字,而它的最大值 4 位於佇列的頭部。

接下來處理第四個數字 2。2 比佇列中的數字 4 小。當 4 滑出視窗之後 2 還是有可能成為滑動視窗的最大值,因此把 2 存入佇列的尾部。現在佇列中有兩個數字 4 和 2,其中最大值 4 仍然位於佇列的頭部。

下乙個數字是 6。由於它比佇列中已有的數字 4 和 2 都大,因此這時 4 和 2 已經不可能成為滑動視窗中的最大值。先把 4 和 2 從佇列中刪除,再把數字 6 存入佇列。這個時候最大值 6 仍然位於佇列的頭部。

第六個數字是 2。由於它比佇列中已有的數字 6 小,所以 2 也存入佇列的尾部。此時佇列中有兩個數字,其中最大值 6 位於佇列的頭部。

接下來的數字是 5。在佇列中已有的兩個數字 6 和 2 裡,2 小於 5,因此 2 不可能是乙個滑動視窗的最大值,可以把它從佇列的尾部刪除。刪除數字 2 之後,再把數字 5 存入佇列。此時佇列裡剩下兩個數字 6 和 5,其中位於佇列頭部的是最大值 6。

陣列最後乙個數字是 1,把 1 存入佇列的尾部。注意到位於佇列頭部的數字 6 是陣列的第 5 個數字,此時的滑動視窗已經不包括這個數字了,因此應該把數字 6 從佇列刪除。那麼怎麼知道滑動視窗是否包括乙個數字?應該在佇列裡存入數字在陣列裡的下標,而不是數值。當乙個數字的下標與當前處理的數字的下標之差大於或者等於滑動視窗的大小時,這個數字已經從滑動視窗中滑出,可以從佇列中刪除了。

public arraylistmaxinwindows(int  num, int size)

劍指offer 滑動視窗最大值

很多題解都是用雙端佇列,但是既然是區間最值得問題,那麼可以用st表 唯一注意的是引數陣列的大小一定要大於視窗的大小,不然沒意義,即 中的len size的時候退出 果然還是引數的合法性一定要考慮,尤其是提示段錯誤的時候,而自己在本地測試沒問題,一般都是引數合法性的問題!一開始就是漏了這個條件,一直提...

劍指offer 滑動視窗的最大值

題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們 的最大值分別為 針對陣列的滑動視窗有以下6個 思路描述 掃瞄給定的陣列,用乙個大小為size的堆維護,將這次的元素加入堆中,找出其中的最大值 然後利用firs...

劍指offer 滑動視窗的最大值

題目 劍指offer 滑動視窗的最大值 暴力列舉視窗。class solution ret.push back max return ret 這個思路也是參考了網上的方法,非常的巧妙。對於,設計乙個que.它的功能是儲存滑動視窗可能的最大值,整個視窗按降序進行排列。隊頭的最大值是當前滑動視窗的最大值...