暴力做法:可以在遍歷陣列的時候,當i-k+1>=0(表示當前滑動視窗的大小達到了k),就遍歷i-k+1 ~ i的所有元素,尋找最大值,
然後把最大值壓入到結果陣列res中,顯然這種做法需要兩重迴圈,時間複雜度為o(n*k)。
我們考慮一下優化,暴力做法在遍歷陣列的時候還需要在內層迴圈遍歷來計算當前視窗內的最大值,而計算當前視窗的最大值,我們可以用
單調佇列進行優化。
考慮這樣一種情況:在長度為k的滑動視窗內,我們要尋找最大值:我們可以從前往後尋找,如果有這樣一種情況,下標i < j,且nums[i] <= nums[j],
則nums[i]肯定不是答案,因為nums[j]比nums[i]大。
不過在下一次遍歷陣列的時候,又(可能)在下乙個滑動視窗內比較nums[i]和nums[j]了,雖然我們在之前就知道了只要有nums[j]在,nums[i]就肯定
不是答案了。
所以我們可以用單調佇列來記錄某個滑動視窗內的元素的大小關係,把當前視窗內的元素入隊(其實是把下標入隊),每個元素入隊之前都會和隊尾元素進行比較,
如果當前元素比隊尾元素大,則隊尾元素肯定不是當前滑動視窗內的最大值(當然也不會是後面的滑動視窗的最大值),我們就一直刪除隊尾元素,直到佇列
為空或者隊尾元素比當前元素大。這時再把當前元素(的下標)入隊,這樣,我們的佇列裡的元素(下標)的值(nums[下標])就是單調遞減的,所以隊頭元素
就是當前滑動視窗內的最大值。
我們只需要注意當滑動視窗移動的時候判斷視窗左端(i - k + 1)和隊頭元素的關係,如果i - k + 1大於q.front(),說明當前
視窗滑動到下乙個位置,之前記錄的隊頭元素下標已經過期了,那就要出隊。
通過這種方式,我們就維護了乙個能夠快速找到當前滑動視窗內元素最大值的雙端佇列。
時間複雜度分析:由於遍歷一遍陣列,每個元素最多入隊和出隊一次,所以時間複雜度為o(n)。
**如下:
class solution
while(q.size() && nums[q.back()] <= nums[i])
q.push_back(i);
if(i - k + 1 >= 0)
}return res;}};
LeetCode 239 滑動視窗最大值
class solution public int maxslidingwindow int nums,int k int numlen nums.length if nums null numlenmaxheap new priorityqueue a,b nums b nums a for in...
LeetCode 239 滑動視窗最大值
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字。滑動視窗每次只向右移動一位。返回滑動視窗最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大值 1...
leetcode239滑動視窗最大值
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字。滑動視窗每次只向右移動一位。返回滑動視窗最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大值 1...