如何在给定的链表中找到循环的起始节点?我们称之为循环点
到目前为止,我已经理解了以下内容(使用慢速/快速指针):
k
k
步骤ahead
慢Cycle point
(LOOP_LENGTH - k)
的{{1}}步behind
或此时指针缓慢Cycle point
步骤才能遇到慢和碰撞(LOOP_LENGTH - k)
步进。 k
有人可以在第9步之后向我解释一下吗?
由于
修改:
我想指出的一点是,一旦进入循环,快速将永远不会超过慢指针。他们会发生碰撞。这就是原因:慢速在i,快速在i-1处假设。当他们移动时,slow => i + 1和fast也将在i + 1,因此碰撞。或者,慢速在i,快速在i-2。下一步,慢 - > I + 1;快:我下一步,慢 - > i + 2,快速:i + 2,因此再次碰撞。如此之快将永远无法超越缓慢,只会在循环中碰撞一次!
答案 0 :(得分:3)
你的6.错了,快指针离那个时间周期点的慢指针还有k步;但最好使用 提前 或 支持 ,而不是远离。另外,k
可能更小,更大或等于loop_length
。
因此,当指针达到循环点时,快速指针在k
之前超前一步,在开始之后,这是k
步。现在,在循环上测量,快速指针在循环点之前步进k % loop_length
。对?如果k = some_n * loop_length + r
,则快速指针在循环点之前步进r
,也就是说,r := k % loop_length
前进。
但这意味着慢速指针在循环中的loop_length - r
步骤 在快速 之前。毕竟这是一个循环。因此,在loop_length - r
个额外步骤之后,快速指针将捕获到慢速指针。对于每一步,慢指针移开,快速移动靠近两个步。
因此我们不知道k
,我们不知道loop_length
或r
,我们只知道m = k + loop_length - r = some_n * loop_length + r + loop_length - r = (some_n+1) * loop_length
。直到两个指针会合点的步骤m
的总数是循环长度的倍数。
所以现在我们重新开始,在开始时有一个新指针,在新的指针前面遇到快速m
步骤。我们以相同的速度移动新的和慢的,每次移动1步,并且在它们应该满足的循环点 - 因为当新指针到达循环点时,第二步仍然是m
步,也就是说,m % loop_length == 0
沿循环前进。这样我们就可以找出k
是什么(我们一直在计算我们的步数)和循环点。
我们再次沿着循环找到loop_length
,直到两人再次相遇。
答案 1 :(得分:0)
首先在第6步中:我认为快速指针距离圆点的距离应该k
。
但是留下这一切。我们现在有两辆车。一辆快车的速度是慢车速度的两倍。
假设快速车在距离圆点k
距离的圆形轨道上开始。
慢车从圆点开始。
现在我说两辆车都会在圆点前k
距离见面。
为什么呢?因为最初快车距离圆点k
距离。第一次完成圆圈时,快速车将覆盖n
距离。现在,快车再次与圆点相距k距离。但是慢车距离圆点n/2
距离。
现在,快车必须覆盖n-2k
距离,以便在圆点之前达到k
距离。慢车必须覆盖n/2 - k = (n-2k) / 2
距离,才能在起点前达到k
距离。 Which is exactly half the distance of the path to be covered by the fast car
。快车的速度是慢车的两倍。
很明显,他们会在圆点前k
距离见面。