首先须要应用Floyd 判圈算法(又称龟兔赛跑算法)的快慢指针思维找到环内快慢指针相遇点c。
如图所示:
假如终点为a,环的入口点为b。终点a到环入口点的间隔为x,环的入口点到快慢指针相遇点间隔为y。
从快慢指针相遇点将慢指针往回倒退y步达到点b,因为快指针速度是慢指针的两倍,故快指针会倒退到c'点,其中b到c'的间隔也为y。即当慢指针走到b点时,快指针的地位在c'。因为慢指针此时走了x步,故快指针从a走2x步达到了c'点。进而等价于快指针从b点走x间隔会走到c'点。
因为bc = bc',故从c点走x间隔会走到b点。a->b == c->b[当然c到b可能走了不止一圈]。
综上,当快慢指针相遇后,设置两指针p1、p2,p1终点为a,p2终点为c,同时一走一步,当p1和p2相遇,即为环的入口点。p1、p2可重用快慢指针。
public ListNode detectCycle(ListNode head) { ListNode slow = head, fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) break; } if (fast == null || fast.next == null) return null; slow = head; while (slow != fast) { slow = slow.next; fast = fast.next; } return slow;}