LeetCode算法總結——鏈表

前言:

做算法題,切記不要眼高手低。爲什麼明明感覺很容易的題目,在寫代碼實現的時候就思路混亂呢?細節!實現的細節是繁雜而且不容易記憶的。有什麼好的辦法嗎?模塊化!細節模塊化。譬如很多問題的解決方法,在首先引入排序後思路就明朗了,問題也就迎刃而解。這就是問題的泛化和規約。排序是個通用的模塊,它的細節、特性和適用的範圍是可以通過多次練習記憶的。除了代碼塊外,數據結構本身也是經常用到的模塊,如LinekedList, HashMap, Array等。在這個意義上,模塊裏面的實現就是具體的“打法”了。掌握了這些模塊的打法,那我就可以上戰場了吧?呸!趙四!那麼對於一道題目,我們還需要弄明白什麼才能不至“看題一時爽,手寫火葬場”的悲劇呢?通用模塊與題目的耦合關係。這種耦合關係就是一種“戰術”,指導着模塊與模塊,模塊與膠水代碼的交互。直接完整搬運整個模塊可能需要較多的膠水代碼輔助,不過思路是清晰的。如果膠水代碼過於難看,則需要考慮模塊的變通性了,巧用模塊,融入到整體代碼中,渾然天成爲高境界。有了“戰術”和“打法”,我們就能高效地解決這些問題了嗎?當然不能!還缺少了最重要的一個東西,“戰略”!“戰略”是“兵來將擋水來土掩”的選擇,它是抽象的,是問題的應對策略。有些題適合用迭代,有些則適合用遞歸,有些用動態規劃,有些用回溯…看,這些就是戰略。

親愛的朋友們,祝你們能夠開心,Goood Luck。

鏈表 LinkedList

翻轉鏈表

206 Reverse Linked List

★ ❥ 📰

  • 戰略:迭代。戰術:輔助previous指針或頭插法,while(head != null)鏈表遍歷,
  • 遞歸:head == null || head.next == null邊界條件保證遞歸結束在最後一個非空節點。先遞歸到頭,在返程修改指針(兩次)。

92 Reverse Linked List II

★★ 📰

  • 模塊化:截取片斷鏈表反轉再和原來的連接起來。❥先走幾步模塊和❥反轉模塊。注意:先走幾步模塊需要走到被截取節點前一個,因此需要使用❥輔助頭節點法。

[25 Reverse Nodes in k-Group]

★★★ 📰

  • 模塊化:先走幾步模塊和反轉模塊。遞歸。翻轉頭幾個,連接到餘下的自身遞歸的結果。這是一種常見的一維數據遞歸的模板。同樣再樹的遞歸構造中,也和此有異曲同工之妙。

鏈表排序

[21. Merge Two Sorted Lists]

★ ❥ 📰

  • 輔助頭節點法。從輔助節點開始,貫穿一條鏈,串起兩條鏈表。

[148. Sort List]

★★ ❥ 📰

  • 歸併排序,模塊化。參考21的歸併函數。
  • 快排,❥交換算法交換節點的值。❥partition函數雙指針同向,注意的一點是鏈表的慢指針在結束時的位置的值應小於參考值,這樣再交換參考節點(第一個)和慢指針節點的值時就方便了。non-stable。(不像數組,索引可以方便的-1+1等操作,怎麼搞都好交換)
  • 插入排序:模塊化,截取節點(剩餘的銜接到前面),然後從前往後比較值插入。輔助頭結點法。

鏈表元素重排

[86. Partition List]

★★ ❥ 📰

  • 輔助頭節點法,兩個輔助頭節點。分拆成小於和大於等於兩個鏈表,然後再合併,注意合併時膠水代碼;

[328. Odd Even Linked List]

★★ ❥ 📰

  • 注意這裏奇數偶數指的是節點的順序,奇數順序的節點在前,偶數在後。❥鏈表的間隔k抽取法。記得奇數鏈表末尾指針置空。

[143. Reorder List]

★★ ❥ 📰

  • L0→Ln→L1→Ln-1→L2→Ln-2→…
  • ❥快慢雙指針半分鏈表。fast=head.next, slow=head, while(fast!=null&&fast.next!=null)。❥合併鏈表模塊,以較短的爲基準,這裏一步要操作兩個方向。

移除鏈表中某節點

[83. Remove Duplicates from Sorted List]

📰

  • 刪除第二個重複節點(跳過,指針置爲空)

[82. Remove Duplicates from Sorted List II]

★★ 📰

  • 輔助頭節點法(aux)。前後兩指針,prev, cur, cur負責判斷cur與cur.next,prev負責鏈接最終的結果。需要注意的一點是,prev從aux開始,cur則從head開始,避免了頭兩個節點的無謂比較。

[19. Remove Nth Node From End of List]

★★ 📰

  • 迭代,先走幾步模塊,❥前後雙指針協同走模塊(一直都是每步一個節點,和快慢雙指針不一樣),輔助頭節點法。

[203. Remove Linked List Elements]

📰

  • 迭代,輔助頭節點法+提前量。

鏈表與環,Math

[2. Add Two Numbers]

★★ ❥ 📰

  • ❥ 兩鏈表相加,比兩數組相加更容易,注意當最後進位是1時,要新建節點。

[445. Add Two Numbers II]

★★ 📰

  • 模塊化,反轉相加再反轉。

[61. Rotate List]

★★ 📰

  • 迭代。左旋x:從前開始第x節點向後切斷;右旋x:從後往前第x節點處向前切斷(類似Find And Delete Nth From end)或等於左旋n-k。❥求鏈表長度模塊(1.同先走幾步模塊幾乎一樣,2. cnt=0; while(head!=null){head = head.next}。

[141. Linked List Cycle]

📰

  • 快慢雙指針ListNode fast = head.next, slow = head; while (fast != null && fast.next != null)…

[142. Linked List Cycle II]

★★ 📰

  • 先快慢指針走到相遇,再用個其他慢指針2從頭開始,兩滿指針走到相遇即可。

[160. Intersection of Two Linked Lists]

📰

  • // 思路:雙指針,一個走鏈表1, 一個走鏈表2,各自走到頭則從另一個鏈表頭開始,直到會和。匯合點即第一個公共點。 雙指針走了相同的距離。

Linked List And Tree

[109. Convert Sorted List to Binary Search Tree]

★★ 📰

  • 遞歸,模塊化。❥有序鏈表轉List, List轉BST(遞歸).

其他

[138. Copy List with Random Pointer]

★★ 📰

  • 迭代。❥在每個節點後插入複製節點, 循環條件while(cur != null)。奇數偶數順序鏈表拆分。

算法模擬:
玩遊戲

發佈了19 篇原創文章 · 獲贊 1 · 訪問量 2138
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章