標籤:演算法 鏈表 指標 leetcode
分為兩步
第一步 還是利用快慢指標,如果有環的話在利用快慢指標終會相會於一個節點。
第二步。然後從這節點出發每次出發走一步,同時從根節點出發每次出發也走一步則他們兩個指標相遇的地方就是環的入口。
第一步好解釋那麼第二步是為什麼呢?
網上有很多解法大都是從數學的角度來分析,有公式也有推算很不直觀,我從圖形的角度來看的話就相對理解起來簡單很多。
將圖攤開成一條線,假設我們有環而且假設快指標就多走了一圈就與慢指標相遇了(多走n圈其實也是一樣的,畫出圖來也不難理解,只是畫起來麻煩索性就以一圈來代表)
紅線表示快指標走了2m 藍線表示慢指標走了m,可以非常直觀的看出來,如果把藍色的線移到上面的紅線上,遮擋住紅線,則紅線還剩下多少
就是一個y 和一個z, 我們知道多走的長度為m,即y+z=m,對比藍色的線也是是m,就是x+z=m
所以直接推出來x = y 那麼我們的第二步想必大家就都理解了。
如果說快節點走了很多圈我們可以自己畫圖發現其實最後還是歸結到上面這個圖的模型上來。
附上代碼
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */public class Solution { public ListNode detectCycle(ListNode head) { if(head==null){ return null; } ListNode slow = head; ListNode fast = head; ListNode now = head; while(fast.next!=null&&fast.next.next!=null){ fast = fast.next.next; slow = slow.next; if(fast==slow){ now = slow; break; } } if(fast.next==null||fast.next.next==null) return null; else{ ListNode start = head; while(start!=now){ start = start.next; now = now.next; } return start; } }}