这两道题目对应着如下两个问题:
- 如何判断链表中存不存在环。
- 找到链表中这个环的入口节点。
链表中是否存在环
对于这个问题,我们先给出解决方案。解决方案
快慢指针思想。慢指针每次走一步,快指针每次走两步。快慢指针若相遇了,则证明存在着环。否则,不存在环。看到这里肯定会好奇,为什么快指针是慢指针的两倍速度呢?三倍,四倍行不行呢? 答案是可以的,只要是快指针是慢指针大于1的整数倍都是可以。
证明
快慢指针如果在环中相遇了,意味着两者的步长差了n圈。所以只要证明两者的步长差会是环长的整数倍即可。
那么假设经过时间T,两指针相遇了,并且环长为C。那么假设快指针的速度是慢指针的K倍,那么两者的时间差就是。
那么只要证明为整数即可。这显然只要
时,
取任意大于1的整数都能达到目的。
这同样也证明了不同K的取值,相遇所花的时间是相同的,只是在环内循环的次数不同。
链表中环的入口
解决方案
同样是快慢指针。慢指针每次走一步,快指针每次走两步。当快慢指针相遇的时候,用一个新的指针指向链表起始节点,然后让慢指针和这个新的指针同时移动。当慢指针和这个新的指针相遇时,那么当前这个节点就是入口节点。这么做是因为证明可以得到当快慢指针在b处相遇时,a=c。
证明
有第一题的证明,我们可以知道,当快慢指针第一次相遇时,慢指针一定是还没走过一圈的。
那么慢指针走过的路程为。
快指针走过的路程则为,化简得到
。
由于快指针是慢指针速度的2倍,那么可以简历上述两个路程之间的等式为
因此,使用两个步长为1的指针同时从相遇点和链表起始点出发,相遇的位置就是入口。
