这两道题目对应着如下两个问题:

  1. 如何判断链表中存不存在环。
  2. 找到链表中这个环的入口节点。

    链表中是否存在环

    对于这个问题,我们先给出解决方案。

    解决方案

    快慢指针思想。慢指针每次走一步,快指针每次走两步。快慢指针若相遇了,则证明存在着环。否则,不存在环。

    看到这里肯定会好奇,为什么快指针是慢指针的两倍速度呢?三倍,四倍行不行呢? 答案是可以的,只要是快指针是慢指针大于1的整数倍都是可以。

证明

快慢指针如果在环中相遇了,意味着两者的步长差了n圈。所以只要证明两者的步长差会是环长的整数倍即可。
那么假设经过时间T,两指针相遇了,并且环长为C。那么假设快指针的速度是慢指针的K倍,那么两者的时间差就是LeetCode 141-142 环形链表 - 图1
那么只要证明LeetCode 141-142 环形链表 - 图2为整数即可。这显然只要LeetCode 141-142 环形链表 - 图3时,LeetCode 141-142 环形链表 - 图4取任意大于1的整数都能达到目的。
这同样也证明了不同K的取值,相遇所花的时间是相同的,只是在环内循环的次数不同。

链表中环的入口

解决方案

同样是快慢指针。慢指针每次走一步,快指针每次走两步。当快慢指针相遇的时候,用一个新的指针指向链表起始节点,然后让慢指针和这个新的指针同时移动。当慢指针和这个新的指针相遇时,那么当前这个节点就是入口节点。这么做是因为证明可以得到当快慢指针在b处相遇时,a=c。
image.png

证明

有第一题的证明,我们可以知道,当快慢指针第一次相遇时,慢指针一定是还没走过一圈的。
那么慢指针走过的路程为LeetCode 141-142 环形链表 - 图6
快指针走过的路程则为LeetCode 141-142 环形链表 - 图7,化简得到LeetCode 141-142 环形链表 - 图8
由于快指针是慢指针速度的2倍,那么可以简历上述两个路程之间的等式为
LeetCode 141-142 环形链表 - 图9
因此,使用两个步长为1的指针同时从相遇点和链表起始点出发,相遇的位置就是入口。