給定乙個陣列 nums 和滑動視窗的大小 k,請找出所有滑動視窗裡的最大值。
示例:
輸入: nums =[1
,3,-
1,-3
,5,3
,6,7
], 和 k =
3輸出:[3
,3,5
,5,6
,7] 解釋:
滑動視窗的位置 最大值
----
----
-------
-----[
13-1
]-35
3673
1[3-
1-3]
5367
313[
-1-3
5]36
7513
-1[-
353]
6751
3-1-
3[53
6]76
13-1
-35[
367]
7
你可以假設k
總是有效的,在輸入陣列不為空的情況下,1 ≤ k ≤ 輸入陣列的大小。
注意:
本題與主站 239 題相同:
最暴力的做法當然是模擬
滑動視窗的過程,掃瞄每個滑動視窗中的所有數字並找出其中的最大值,這樣的複雜度是o(k
n)o(kn)
o(kn
)的。顯然題目出在這裡肯定不是要我們用暴力解法。
視窗向右滑動的過程實際上就是將處於視窗的第乙個數字刪除,同時在視窗的末尾新增乙個新的數字,這就可以用雙向佇列
來模擬,每次把頭部的數字彈出,再把新的數字新增到佇列尾部,然後找佇列中最大的元素即可。
為了使用o(1
)o(1)
o(1)
的時間就能找到最大的元素,我們並不把滑動視窗的每個數值都存入佇列,而是只把有可能成為滑動視窗最大值的數值存入佇列。
當前視窗中元素大於k
個時,說明隊頭的元素已經從視窗滑出,需要從佇列頭部出隊
。
隊尾已有的數字小於等於當前要存入的數字,那麼隊尾這些數字已經不可能是滑動視窗的最大值,因為待存入的數字比它們大,還要比他們晚滑出視窗。所以隊尾這些元素都要從隊尾出隊
。
當前面元素都滑出當前視窗時,當前元素可能會是後面視窗的最大值,所以當前元素無論如何都要入隊。
因此我們維護乙個雙向佇列,佇列放的是元素的下標。我們維護該雙端佇列的隊頭是整個佇列的最大元素所在下標
。
時間複雜度:每個元素最多入隊出隊一次,複雜度為o(n
)o(n)
o(n)
class
solution
//當前元素大於隊尾元素,則隊尾這些元素只要當前元素在,就不可能是視窗中的最大值,可以直接拿走了
while
(!deque.
isempty()
&& nums[i]
>= nums[deque.
peeklast()
])//當前面元素都滑出當前視窗時,當前元素可能會是後面視窗的最大值,所以當前元素無論如何都要入隊
//注意佇列中存的是元素在陣列中的下標,方便判斷視窗中當前元素有多少個了
面試題59 I 滑動視窗的最大值
題目 給定乙個陣列 nums 和滑動視窗的大小 k,請找出所有滑動視窗裡的最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大值 1 3 1 3 5 3 6 7 3 1 3 1 3 5 3 6 7 3 1 3 1 3 5 ...
59 滑動視窗的最大值
滑動視窗的最大值 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 57.cpp 定義控制台應用程式的入口點。include stdafx.h include include...
劍指offer59 I 滑動視窗的最大值
題目描述 給定乙個陣列 nums 和滑動視窗的大小 k,請找出所有滑動視窗裡的最大值。解析解法一 沒有任何優化,直接擷取陣列,依次遍歷求各陣列最大值 public int maxslidingwindow int nums,int k maxnums i max return maxnums 解法二...