牛客解題思路 滑動視窗的最大值 糾錯記錄

2021-10-24 00:16:01 字數 2901 閱讀 6451

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

這一題我首先想到的就是堆,但是我當時並不知道priorityqueue有乙個remove方法是可以刪除指定的元素的,知道了這個方法當然就變得簡單了:

public arraylist

maxinwindows

(int

num,

int size)

return ret;

}

這裡我仍然對這個remove方法充滿了疑惑,因為如果num[i]有兩個一樣的元素存在於堆中那麼移除乙個還是兩個呢,於是我開啟了eclipse看了一下原始碼,remove方法的輸入是個object物件,先找到該物件的索引,然後刪除,且只刪除第乙個出現的物件。什麼是第乙個出現的,就是最先放入堆的,同樣,add方法的add操作中,索引也是不斷遞增的。

但是如果我就是忘了heap.remove這個方法應該怎麼辦呢?而且這個heap.remove操作很浪費時間。

那我們可以使用佇列呀,佇列的特點就是先進先出,那麼我們剛好可以模擬這個滑動視窗。

舉個例子,如果序列是13246859,那麼在滑動視窗一旦包含8後,最大值完全不需要考慮8以前的數字了,即使其還在滑動視窗中,那麼如果我們使用佇列的話,也就是小於8且在8之前的元素可以直接讓其出隊,因此滑動視窗每來乙個數(還未進佇列)就可以進行這個判斷,讓小於該數且在隊前(思考一下,這裡的隊前是指的隊首還是隊尾呢,因為此時隊首隊尾都是在該數之前的)的元素直接出隊,那麼此時的隊首一定是當前滑動視窗中的最大值了。

因為我們需要頻繁的從隊頭隊尾插入和刪除元素,我們可以使用雙端佇列:

linkedlist

qmax =

newlinkedlist

<

>()

;

其實這樣也可以:

queue

qmax =

newlinkedlist

<

>()

;

但是這樣就只能用poll和add和peek啦,也是可以完成所有操作的。

於是我就寫出了這樣的**:

public arraylist

maxinwindows

(int

num,

int size)

arraylist

result =

newarraylist

<

>()

;//雙端佇列,用來記錄每個視窗的最大值下標

queue

qmax =

newlinkedlist

<

>()

;for

(int i =

0; i < num.length; i++

)while

(!qmax.

isempty()

&& num[qmax.

peek()

]< num[i]

) qmax.

add(i)

;//判斷隊首元素是否過期

if(qmax.

peek()

== i - size)

//向result列表中加入元素

if(i >= size -1)

}return result;

}

結果當然是又翻車了(;´༎ຶд༎ຶ`),因為我僅僅只考慮了隊頭元素最大,當隊頭過期後,佇列裡面的順序就不對了,例如測試用例[2,3,4,2,6,2,5,1],3在某時刻佇列中的情況【5,2,6】,此時6再過期則有【1,5,2】這時本應該在隊頭的5卻不在了,所以這樣寫不對!!!其實當佇列中只有【2,6】(5還沒進來)時5應該先與2比較!!!!所以這裡應該注意的是,前面的敘述有問題,應該先與隊尾比較!!!

所以這樣一來還是用linkedlist qmax = new linkedlist<>();方便,因為裡面的方法比較豐富o( ̄▽ ̄)o

因此,要改的關鍵部分就是這裡:

while

(!qmax.

isempty()

&& num[qmax.

peeklast()

]< num[i]

)

正確**如下:

public arraylist

maxinwindows

(int

num,

int size)

arraylist

result =

newarraylist

<

>()

;//雙端佇列,用來記錄每個視窗的最大值下標

linkedlist

qmax =

newlinkedlist

<

>()

;for

(int i =

0; i < num.length; i++

) qmax.

addlast

(i);

//判斷隊首元素是否過期

if(qmax.

peekfirst()

== i - size)

//向result列表中加入元素

if(i >= size -1)

}return result;

}

另外,result.add(num[qmax.peekfirst()])記住不是peeklast()!!!

並且需要先移除過期元素再更新result!!!

滑動視窗最大值

題目描述 給定乙個陣列和滑動視窗的大小,找出所有滑動視窗裡數值的最大值。例如,如果輸入陣列及滑動視窗的大小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 解釋 滑動視窗的位置 最大...