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