环形链表要点
1、判断该链表有没有环;
2、环的入口在哪;
要点一:
我们定义两个指针,一个快指针(fast)一次走两步,一个慢指针(slow)一次走一步,如果最后他们相遇了,说明该链表有环
要点二:
下图是《代码随想录》里的图,下图各类距离变量用于公式计算
第一次相遇时
slow指针走过的节点数:x+y
fast指针走过的节点数:,n代表的是没相遇前,fast走得圈数n
因为slow指针一次只走一步,fast指针一次走两步,所以有:
(slow走过的节点) x 2 = fast指针走过的节点数
即 2(x+y)= x+y+ n(y+z)化简得:x = (n-1)(y-z) + z , 这个式子意味着,如果n=1时,在他们第一次相遇后,设置一个指针从头节点重新出发,然后再设置一个指针从相遇点出发,走完 x=z步后,再次相遇点便是环形入口节点;
当n > 1时,依然设置两个指针,一个指针从头节点重新出发,然后再设置一个指针从相遇点出发,走完 x = (n-1)(y-z) + z ,二者依然还在环形入口相遇,因为从相遇点出发的节点只是转了 (n-1)(y-z)圈回到第一次相遇点,然后再走z步,x的意思是,从头结点到环形入口的距离,所以第二次相遇时,他们依然在环形入口。
代码如下:
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;。
//第一次相遇
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
slow = head;//slow从头结点重新开始
//第二次相遇
while (slow != fast && fast!=null) {
slow = slow.next;
fast = fast.next;
}
//没有环
if (fast == null || fast.next==null) {
return null;
}
return slow;
}
--------------------------------------------------------------------------------------------------------------------------------
本人是刷《代码随想录》这本书时记录一下自己的学习笔记