此题没有代码,是一道面试题。题目很好理解,有个链表,先判断是否有环,若是有环则求出环的入口。面试
这道题跟好几位offer收割机讨论过,基本都是已知leetcode或哪里的方法,证实该方法的正确性。指针
我和我家阳哥,试图证实,策略是能够推导出来的。证实以下:code
首先,要判断一个链表是否有环,机智的作法是快慢指针,令快指针fast每次走两步,慢指针slow每次走一步,那么fast若是能和slow相遇,就证实,链表中有环。leetcode
那么有环以后,如何寻找环的入口呢?ast
(1)首先,咱们定义几个变量:变量
(2)其次,咱们须要证实一个结论---slow入环后,一圈以内一定与fast相遇List
这个结论其实很好证实,咱们用反证法。假设slow走了一圈又回到了RingEntry,这一过程当中,都没与fast相遇。当slow回到RingEntry时,fast一定在距RingEntry为pos的位置。这一状态与slow刚入环时的状态同样,在这一圈中slow与fast都没有相遇,那么以后只会不断重复以前的路径,永不会相遇。方法
由于咱们坚信 有环的话,slow和fast必相遇的,于是上述假设不成立,slow入环后,一圈以内一定与fast相遇。链表
(3)有了(2)的结论,就能够得出下列等式:co
2x = x + k * r + pos(k表示fast在环中已经绕的圈数) ------> pos = x - k * r
2y - y = r - pos ------> y = r - pos
r - y = r - r + pos = pos = x - k * r ------> r - y + k * r = x
之因此要把k * r移到 等号 的左边,是由于 k * r 表明着绕着环 k 圈,到达的位置仍是 r - y步后到达的位置。
根据最后一个等式,咱们就能够看出,slow再向前走 x 步 必定会到RingEntry。
因此寻找环入口的方式为:相遇点后,slow 从相遇点开始,tmp从 ListHead 开始,同时每次走一步,两个相遇点就是RingEntry!