也許這種資料結構的名字你沒聽過, 其實沒啥難的, 就是⼀個「佇列
」 , 只是使⽤了⼀點巧妙的⽅法,使得佇列中的元素單調遞增(或遞減)
。 這個資料結構有什麼⽤? 可以解決滑動窗⼝
的⼀系列問題。
看⼀道 leetcode 題⽬, 難度 hard:
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。
返回滑動視窗中的最大值。
示例:
輸入: 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
⼀、 搭建解題框架在⼀堆數字中, 已知最值, 如果給這堆數新增⼀個數, 那麼⽐較⼀下就可以很快算出最值; 但如果減少⼀個數, 就不⼀定能很快得到最值了, ⽽要遍歷所有數重新找最值回到這道題的場景, 每個窗⼝前進的時候
, 要新增⼀個數同時減少⼀個數
,所以想在 o(1
)o(1)
o(1)
的時間得出新的最值, 就需要「單調佇列」 這種特殊的資料結構來輔助了
⼀個「單調佇列」 的操作也不多:
這個思路很簡單, 能理解吧? 下⾯我們開始重頭戲, 單調佇列的實現。
⼆、 實現單調佇列資料結構
⾸先我們要認識另⼀種資料結構:deque, 即雙端佇列
。 很簡單:
class deque
;
這些操作的複雜度都是 o(1
)o(1)
o(1)
「單調佇列
」 的核⼼思路和「單調棧」 類似。單調佇列的 push ⽅法依然在隊尾新增元素, 但是要把前⾯⽐新元素⼩的元素都刪掉
:
class monotonicqueue
};
你可以想象, 加⼊數字的⼤⼩代表⼈的體重, 把前⾯體重不⾜的都壓扁
了,直到遇到更⼤的量級才停住。
如果每個元素被加⼊時都這樣操作, 最終單調佇列中的元素⼤⼩就會保持⼀個單調遞減的順序
, 因此我們的max()
api 可以可以這樣寫:
int
max(
)
pop()
api 在隊頭刪除元素 n, 也很好寫:
void
pop(
int n)
之所以要判斷 data.front() == n , 是因為我們想刪除的隊頭元素 n 可能已經被「壓扁
」 了, 這時候就不⽤刪除了⾄此, 單調佇列設計完畢, 看下完整的解題**:
class monotonicqueue
intmax()
void
pop(
int n)};
vector<
int>
maxslidingwindow
(vector<
int>
& nums,
int k)
else
}return res;
}
讀者可能疑惑, push 操作中含有 while 迴圈, 時間複雜度不是 o(1
)o(1)
o(1)
呀, 那
麼本演算法的時間複雜度應該不是線性時間吧?
單獨看 push 操作的複雜度確實不是 o(1
)o(1)
o(1)
, 但是演算法整體的複雜度依然是o(n
)o(n)
o(n)
線性時間。 要這樣想, nums 中的每個元素最多被 pus
hbac
kpush_back
pushb
ack 和pop
back
pop_back
popba
ck⼀次, 沒有任何多餘操作, 所以整體的複雜度還是 o(n
)o(n)
o(n)
。空間複雜度就很簡單了, 就是窗⼝的⼤⼩o(k
)o(k)
o(k)
。
單調佇列 滑動視窗
nkoj 2152 description 給你乙個長度為n n 10 6 的陣列,乙個長為k的滑動的窗體從最左移至最右端,你只能見到視窗的k個數,每次窗體向右移動一位,找出窗體所包含的數字的最大和最小值,如下表所示 k的值為3 視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 ...
滑動視窗 單調佇列
給定乙個大小為n 106的陣列。有乙個大小為k的滑動視窗,它從陣列的最左邊移動到最右邊。您只能在視窗中看到k個數字。每次滑動視窗向右移動乙個位置。以下是乙個例子 該陣列為 1 3 1 3 5 3 6 7 k為3。視窗位置 最小值 最大值 1 3 1 3 5 3 6 7 1 3 1 3 1 3 5 3...
單調佇列 滑動視窗
p1886 滑動視窗 模板 單調佇列 有乙個長為 n 的序列 a,以及乙個大小為 k 的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。如果按照暴力方法做的話,每一次判斷相鄰的k個數的最大值和最小值,複雜度為o n k 肯定會超時,因此就想到把每次的最大值和...