300分鐘搞定資料結構與演算法課程學習2 佇列

2021-10-05 15:44:13 字數 1461 閱讀 4521

佇列(queue)

特點:和棧不同,佇列的最大特點是先進先出(fifo),就好像按順序排隊一樣。對於佇列的資料來說,我們只允許在隊尾檢視和新增資料,在隊頭檢視和刪除資料。

實現:可以借助雙鏈表來實現佇列。雙鏈表的頭指標允許在隊頭檢視和刪除資料,而雙鏈表的尾指標允許我們在隊尾檢視和新增資料。

應用場景:直觀來看,當我們需要按照一定的順序來處理資料,而該資料的資料量在不斷地變化的時候,則需要佇列來幫助解題。在演算法面試題當中,廣度優先搜尋(breadth-first search)是運用佇列最多的地方,我們將在第 06 課時中詳細介紹。

雙端佇列(deque)

特點:雙端佇列和普通佇列最大的不同在於,它允許我們在佇列的頭尾兩端都能在 o(1) 的時間內進行資料的檢視、新增和刪除。

實現:與佇列相似,我們可以利用乙個雙鏈表實現雙端佇列。

應用場景:雙端佇列最常用的地方就是實現乙個長度動態變化的視窗或者連續區間,而動態視窗這種資料結構在很多題目裡都有運用。

例題分析

leetcode 第 239 題:給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字,滑動視窗每次只向右移動一位。返回滑動視窗最大值。

注意:你可以假設 k 總是有效的,1 ≤ k ≤ 輸入陣列的大小,且輸入陣列不為空。

示例:給定乙個陣列以及乙個視窗的長度 k,現在移動這個視窗,要求列印出乙個陣列,陣列裡的每個元素是當前視窗當中最大的那個數。

輸入:nums = [1, 3, -1, -3, 5, 3, 6, 7],k = 3

輸出:[3, 3, 5, 5, 6, 7]

解題思路

思路 1:移動視窗,掃瞄,獲得最大值。假設陣列裡有 n 個元素,演算法複雜度就是 o(n)。這是最直觀的做法。

思路 2:利用乙個雙端佇列來儲存當前視窗中最大那個數在陣列裡的下標,雙端佇列新的頭就是當前視窗中最大的那個數。通過該下標,可以很快地知道新的視窗是否仍包含原來那個最大的數。如果不再包含,我們就把舊的數從雙端佇列的頭刪除。

因為雙端佇列能讓上面的這兩種操作都能在 o(1) 的時間裡完成,所以整個演算法的複雜度能控制在 o(n)。

1 初始化視窗 k=3,包含 1,3,-1,把 1 的下標壓入雙端佇列的尾部;

2 把 3 和雙端佇列的隊尾的資料逐個比較,3 >1,把 1 的下標彈出,把 3 的下標壓入隊尾;

3 -1<3,-1 壓入雙端佇列隊尾保留到下一視窗進行比較;

4 3 為當前視窗的最大值;

5 視窗移動,-3 與隊尾資料逐個比較,-3<-1,-3 壓入雙端佇列隊尾保留;

6 3 為當前視窗的最大值;

7 視窗繼續移動,5>-3,-3 從雙端佇列隊尾彈出;

8 5>-1,-1 從隊尾彈出;

9 3 超出當前視窗,從佇列頭部彈出;

10 5 壓入佇列頭部,成為當前視窗最大值;

11 繼續移動視窗,操作與上述同理。

視窗最大值只需讀取雙端佇列頭部元素。

300分鐘搞定資料結構與演算法課程學習 2 列表

鍊錶 linkedlist 單鏈表 鍊錶中的每個元素實際上是乙個單獨的物件,而所有物件都通過每個元素中的引用字段鏈結在一起。雙鏈表 與單鏈表不同的是,雙鏈表的每個結點中都含有兩個引用字段。鍊錶的優缺點 鍊錶的優點如下 鍊錶能靈活地分配記憶體空間 能在 o 1 時間內刪除或者新增元素,前提是該元素的前...

300分鐘搞定資料結構與演算法課程學習2 棧

棧 stack 特點 棧的最大特點就是後進先出 lifo 對於棧中的資料來說,所有操作都是在棧的頂部完成的,只可以檢視棧頂部的元素,只能夠向棧的頂部壓 資料,也只能從棧的頂部彈出資料。實現 利用乙個單鏈表來實現棧的資料結構。而且,因為我們都只針對棧頂元素進行操作,所以借用單鏈表的頭就能讓所有棧的操作...

3分鐘速讀原著《Java資料結構與演算法》 二

1.簡單排序的種類 2.簡單排序之間的比較 3.小結舉例說明 在郵局經常需要去處理郵件,郵件會從下至上堆積成為乙個棧,此時處理的方式就是先處理最上面的郵件,這種方式只有能夠在合理的時間內從容處理完所有的信件,這種工作方式才不會產生太 煩,否則最底層的信件就將會永遠無法得到處理 1.棧的實戰示例 2....