1.链表头节点就是环形入口
定义两个指针指向头结点,慢指针一次走一步,快指针一次走两步,再次相遇时,快慢指针相差的步数就是环形链表的节点数
2.链表头结点不是环形入口
依旧定义快慢指针,设头结点到环形入口的长度是x,环形长度是y。
快指针一次两步,慢指针一次一步,当快慢指针相遇时,设慢指针在环内走了k步(慢指针在绕环一圈前就会被快指针追上),块指针在环内绕了n圈。那么此时慢指针走了x+k步,快指针走了x+k+ny。
由于快指针速度是慢指针的两倍,所以x+k+ny = 2(x+k)。x=ny-k。从公式可以看出,一个指针a从头结点开始移动,另一个指针b从k位置开始移动,当a移动x步到达环形入口,b正好与a相遇。由此可以算出环形入口的位置。
public ListNode detectCycle(ListNode head) {
if (head == null) {
return null;
}
ListNode slow = head, fast = head;
while (fast != null) {
slow = slow.next;
if (fast.next != null) {
fast = fast.next.next;
} else {
return null;
}
if (fast == slow) {
ListNode ptr = head;
while (ptr != slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
}