443,滑動視窗最大值

2021-10-09 11:54:01 字數 3021 閱讀 3350

給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。

返回滑動視窗中的最大值。

示例:

暴力求解

最簡單的一種方式就是暴力求解,原理其實很簡單,就是視窗在往右滑動的過程中,每滑動一步就計算視窗內最大的值,就以上面的資料畫個圖來看下

**比較簡單,直接看下

public

int[

]maxslidingwindow

(int

nums,

int k)

res[i]

= max;

}return res;

}

如果看過之前講的378,資料結構-7,堆我們還可以使用堆來解決,這裡可以使用最大堆,堆頂的元素是最大的,因為這題求的就是視窗內的最大值,堆的大小就是視窗的大小。因為堆的每次刪除和新增都會涉及到往下調整和往上調整,所以效率一般不是很高,也可以看下,這裡就是用priorityqueue來代替堆

public

int[

]maxslidingwindow

(int

nums,

int k)

}return res;

}

雙端佇列求解我們知道一般的佇列都是先進先出的,但雙端佇列兩端都可以進出,如果對雙端佇列不熟悉的可以看下之前寫的359,資料結構-3,佇列。

使用雙端佇列首先要搞懂乙個問題,就是在雙端佇列中,要始終保證隊頭是佇列中最大的值。那怎麼保證呢,就是在新增乙個值之前,比他小的都要被移除掉,然後再新增這個值。我們舉個例子,比如視窗大小是3,雙端佇列中依次新增3個值[4,2,5],在新增5之前我們要把4和2給移除,讓佇列中只有乙個5,因為視窗是往由滑動的,當新增5的時候,4和2都不可能再成為最大值了,並且4和2要比5還先出佇列,搞懂了上面的過程我們隨便畫個圖看下

搞懂了上面的過程**就很容易寫了,再看**之前先來看一下雙端佇列常用的幾個函式

**如下

public

int[

]maxslidingwindow

(int

nums,

int k)

//在新增乙個值之前,前面比他小的都要被移除掉,並且還要保證視窗

//中佇列頭部元素永遠是佇列中最大的

while

(!qeque.

isempty()

&& nums[qeque.

peeklast()

]< nums[i]

)//當前元素的下標加入到佇列的尾部

qeque.

addlast

(i);

//當視窗的長度大於等於k個的時候才開始計算(注意這裡的i是從0開始的)

if(i >= k -1)

}return res;

}

兩端掃瞄解決這個不太容易想到,就是根據視窗大小把陣列分成n個視窗,每個視窗分別從左往右和從右往左掃瞄,記錄掃瞄的最大值,就像下面這樣

視窗分好之後乙個從前往後掃瞄乙個從後往前掃瞄,記錄每個視窗掃瞄的最大值。我們取視窗內的最大值的時候,如果視窗在原陣列中開始的下標正好是k的倍數,比如下面這樣,他的最大值很容易找

但如果視窗滑動到下面這種情況下

如果要找這個視窗的最大值,我們就要選視窗內從左邊掃瞄最後乙個和從右邊掃瞄最後乙個(視窗內從左邊數第乙個)的最大值,也就是下面這樣

res[j]

= math.

max(maxright[i]

, maxleft[i + k -1]

);

為什麼要這樣選,大家可以想一下,因為如果選擇從左邊掃瞄的第乙個值的話,那麼這個值可能不是當前視窗內的值,同理從右邊掃瞄的也一樣。

搞懂了上面的分析過程**就很容易寫了

public

int[

]maxslidingwindow

(int

nums,

int k)

//返回的結果值

int[

] res =

newint

[len - k +1]

;for

(int i =

0, j =

0; i < res.length; i++

)return res;

}

總結滑動視窗題,第一種暴力求解一般都能想到,但效率很差,最常見的就是第2種使用雙端佇列,第3種方式效率也挺高的,但一般不太容易想到。

滑動視窗最大值

題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為 針對陣列的滑動視窗有以下6個 幾個注意點 利用雙端佇列實現,如果後者比前者大,前者丟擲,後者進,如果比前者小,壓入佇列,判斷隊頭是否過期,這就需...

滑動視窗最大值

給定乙個陣列和滑動視窗的大小,請找出所有滑動視窗裡的最大值。public class 滑動視窗的最大值 if num.length size size 1 用來儲存可能是滑動視窗最大值的數字的下標 linkedlist indexdeque newlinkedlist for int i 0 i s...

滑動視窗最大值

給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。返回滑動視窗中的最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大...