给定一个链表,寻找其中环的起点,如果不存在环,则返回null
思路:设置两个指针,前一个每步向前移动两个节点,后一个每步移动一个节点,如果存在环,那么两个指针将会在环中相遇。假设相遇时,后一个指针移动了k步,那么前一个指针就移动了2k步。设链表到环的起点之间的步数为s,从环的起点到相遇点的步数为m,整个环的长度为r,那么在第一次两个指针相遇的时候,后一个指针所走的步数为k=s+m+ar,其中a为指针在环中循环的次数;而前一个指针走过的步数为2k=s+m+br,b是指针在环中循环的次数,由上面两个式子知s+m=(b-2a)r => s=(b-2a)r-m。于是,如果一个指针从链表头开始出发,另一个指针从相遇点开始出发,当第一个指针到达环的起点时,第二个指针也会刚好循环回到环的起点,所以,当这两个指针相遇时的点就是环的起点。
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null)
return null;
ListNode fast = head;
ListNode slow = head;
ListNode p = head;
while(fast.next != null || fast.next.next != null){
if(fast == slow){//meet at slow
while(p != slow){
p = p.next;
slow = slow.next;
}
return p;
}
fast = fast.next.next;
slow = slow.next;
}
return null; //meet the end of the list
}