《消逝的光芒2》前幾個DLC地點不會離城市太遠
阿新 • • 發佈:2022-06-02
142.環形連結串列 II
方式一:雜湊表
我們遍歷連結串列中的每個節點,並將它記錄下來;一旦遇到了此前遍歷過的節點,就可以判定連結串列中存在環。藉助雜湊表可以很方便地實現。
public class Solution { public ListNode detectCycle(ListNode head) { Set<ListNode> set = new HashSet<ListNode>(); while (head != null) { if (set.contains(head)) { return head; } else { set.add(head); } head = head.next; } return null; } }
方式二:快慢指標
這類連結串列題目一般都是使用雙指標法解決的,例如尋找距離尾部第K個節點、尋找環入口、尋找公共尾部入口等。
雙指標第一次相遇:
設 fast 和 slow 指向連結串列頭部 head,fast走2步,slow走1步
-
第一種結果:fast 指標走到連結串列末端,表示連結串列無環,返回 null
-
第二種結果:當 fast == null時,兩指標第一次在環裡相遇
-
- 設連結串列一共有 x 個結點,其中連結串列頭部到環入口有 a 個結點,連結串列環有 b 個結點
-
-
- fast 的步數是 slow 步數的 2 倍 f = 2s
- fast 比 slow 多走了 n 個 環的長度 f = s + nb
-
-
- 有上式可得
-
-
- f = 2nb,s = nb
-
雙指標第二次相遇:
- slow指標位置不變 ,將fast指標重新指向連結串列頭部節點;slow和fast同時每輪向前走111步;
- 當 fast 指標走到f=af = af=a 步時,slow 指標走到步s=a+nbs = a+nbs=a+nb,此時兩指標重合,並同時指向連結串列環入口 。
public class Solution { public ListNode detectCycle(ListNode head) { ListNode fast = head, slow = head; while (true) { if (fast == null || fast.next == null) return null; fast = fast.next.next; slow = slow.next; if (fast == slow) break; } fast = head; while (slow != fast) { slow = slow.next; fast = fast.nxet; } return fast; } }