239 滑動視窗最大值

2021-10-13 18:23:25 字數 2137 閱讀 5144

239. 滑動視窗最大值

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

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

示例 1:

輸入: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] 3 6 7 5

1 3 -1 [-3 5 3] 6 7 5

1 3 -1 -3 [5 3 6] 7 6

1 3 -1 -3 5 [3 6 7] 7

示例 2:

輸入:nums = [1], k = 1

輸出:[1]

示例 3:

輸入:nums = [1,-1], k = 1

輸出:[1,-1]

示例 4:

輸入:nums = [9,11], k = 2

輸出:[11]

示例 5:

輸入:nums = [4,-2], k = 2

輸出:[4]

分析:這是一道典型的滑動視窗問題,樸素的做法自然就是每個區間計算一次最大值,複雜度為o(nk)。如果讀者有學習過st表解決rmq問題的話,可以將此題的複雜度優化到o(nlogk)。我們首先來看看本題存在的多餘計算,以下圖為例:

在視窗為3的情況下,9在這三種情況下都存在,且是最大值,因此這三個區間,維護最大值就可以了,很多值是沒有必要維護的。

我們維護乙個單調佇列結構,一方面,我們保持整個佇列是單調遞減的,如果對頭元素已經不在當前的視窗內,則彈出;另一方面,當插入新元素時,如果隊尾比新元素小,則不斷彈出,直到佇列空或者隊尾元素大於新元素。

第一點相信很好理解,關鍵是第二點,為什麼可以彈出那些小的元素,事實上,由於我們是不斷向後遍歷的,因此我們不再需要考慮前面的區間,而後面的區間,會用到前面元素的可能性越來越低,越後面可能性越低,同時,一旦這些後面的區間包含了大的值,那麼舊的小值就不可能成為答案。

以題示為例:nums = [1,3,-1,-3,5,3,6,7], k = 3

初始化單調佇列時,我們只考慮前兩個元素,我們會得到單調隊列為:3

不保留1的原因在於,如果後面的區間包含了1,那麼勢必會包含3,而由於3的存在,那麼1自然就不可能為最大值,因此不需要保留他。

嘗試加入-1:-1<3,可以直接加入,佇列變為:3 -1

嘗試加入-3:-3

嘗試加入5:首先,對頭元素已經不在當前的區間內了,所以首先剔除,佇列變為:-1 -3,然後,根據單調性維護原則,佇列最終變為:5

後續請讀者自行嘗試。。。

class solution ;

vectormaxslidingwindow(vector& nums, int k)

window.push_back(node);

}for(; i < n; ++ i)

while( !window.empty() && i - window.front().index >= k )

window.push_back(node);

ans.push_back(window.front().value);

}return ans;}};

239 滑動視窗最大值

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

239 滑動視窗最大值

239.滑動視窗最大值 solution deque solution maxindex 暴力法的時間複雜度為 o n k 弊端為每次掃瞄視窗的最大值,每兩次掃瞄之間都會存在重複的值比較,已經知道了他們的最大值是誰了,所以要減少比較次數 為什麼新增的是索引 將i加到隊尾 deque.addlast ...

239 滑動視窗最大值

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