对于一个环形链表,我们要找到他的起点。可以通过如下推导。
我们设置两个快慢指针,相遇的点为X.
到起点的距离是T,圈长是C,第一次相交的点是X
(T+X)2=T+NC+X
化出来T=N*C-X
也就是说我们把一个节点放头部重新遍历,再次相交的点就是入环处。
这里面细节非常多。
首先快慢指针不能岔开设置,不然推导的T不一样了。
其次一开始就要移动,不然一开始指针一样了。
然后快指针相遇后只能一步一步移动了。
最后要记得特判fast的下一个节点是否存在。
/**
* 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 fast = head;
ListNode slow = head;
while(fast!=null){
if(fast.next!=null)
fast = fast.next.next;
else
return null;
slow = slow.next;
if(fast==slow){
fast = head;
while(fast!=slow){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
return null;
}
}