142. Linked List Cycle II

来源:互联网 发布:centos安装wordpress 编辑:程序博客网 时间:2024/06/09 23:06

  

  设:链表头是X,环的第一个节点是Y,slow和fast第一次的交点是Z。各段的长度分别是a,b,c,如图所示。环的长度是L。slow和fast的速度分别是qs,qf。

第一次相遇时slow走过的距离:a+b,fast走过的距离:a+b+c+b。

因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(a+b) = a+b+c+b,可以得到a=c(这个结论很重要!)

我们发现L=b+c=a+b,也就是说,从一开始到二者第一次相遇,循环的次数就等于环的长度。

我们已经得到了结论a=c,那么让两个指针分别从X和Z开始走,每次走一步,那么正好会在Y相遇!也就是环的第一个节点。

public static ListNode detectCycle(ListNode head) {    ListNode slow = head;    ListNode fast = head;    while (true) {        if (fast == null || fast.next == null) {            return null;    //遇到null了,说明不存在环        }        slow = slow.next;        fast = fast.next.next;        if (fast == slow) {            break;    //第一次相遇在Z点        }    }    slow = head;    //slow从头开始走,    while (slow != fast) {    //二者相遇在Y点,则退出        slow = slow.next;        fast = fast.next;    }    return slow;}

原创粉丝点击