代码可以参考
网上找了很多答案,感觉他们理解还是差了一点
本文讲的是快慢指针那种解法
数学解法一
(快指针一定会比慢指针先进入环里,如果快慢指针相遇,那么快指针一定至少比慢指针领先一圈,也就是下面 k>1)
(假设现在快慢指针相遇,现在都在相遇点)
慢指针走过的路: a + j(b+c) + b
a、b、c就是图中的a、b、c,(b+c)为一圈的路程,j为常数,表示走了j圈 (j>=0)
快指针走过的路: a + k(b+c) + b
a、b、c就是图中的a、b、c,(b+c)为一圈的路程,k为常数,表示走了k圈 (k>=1)
因为快指针走过的路程是慢指针的两倍,由此我们得到下面等式:
快指针路程=2*慢指针路程
a + k(b+c) + b = 2* (a + j(b+c) + b)
开始化简
a + k(b+c) + b = 2* (a + j(b+c) + b)
a + k(b+c) + b = 2a + 2j(b+c) + 2b
k(b+c) = a + 2j(b+c) + b
(k-2j)(b+c) = a + b
(k-2j)(b+c) - b = a
(k-2j-1)(b+c) + (b + c) -b = a //借(k-2j)(b+c)一个b+c出来
(k-2j-1)(b+c) + c = a
由此得到
a = (k-2j-1)(b+c) + c
解释,即我走一次a的路程,等于我走了n圈b+c的路程再走一次c的路程(n为b+c前面的常数)
回到上图,假设现在快慢指针都在相遇点,这个时候,我使用一个慢指针1从相遇点开始走,另外一个慢指针2从最左边的起点开始走,假设现在都走了 c 的路程,慢指针1则回到环的起点,接下来慢指针1只需要走 (k-2j-1)(b+c) 的路程也就是 (k-2j-1)圈,就能走完a的路程,此时慢指针2也走完了a的路程,则他们在环的起点相遇
所以,从相遇点使用两个慢指针,一个从相遇点走,一个从最左边的起点走,是能在环的起点相遇的
数学解法二
假设起点到入口节点的距离为 a,环的节点数是n,在上图中a为 2,n为4
a+n的大小等于所有的节点数量
如果我们(从最左侧起点)走 a+n个箭头,或者说a+n个next,那么一定会回到环的入口节点
求n很简单,用快慢指针找到相遇点,然后相遇点一定在环里,我们只需要从相遇点一直next到再次遇到相遇点,并统计遇到的节点数量,即为n
上图假设(由快慢指针)得到相遇点为 5,只需要走 2(即a的大小)个next,就能到达环的起点,a不需要知道大小,我们只需要一个慢指针1,从左边起点出发,另外一个慢指针2从相遇点出发,他们同时走a步必相遇