解释循环链表中查找循环开始节点的工作原理?
我知道Tortoise和Hare的会议总结了循环的存在,但是如何将兔子移动到链接列表的开头同时将野兔保持在会场,然后一步一步地移动两个步骤使它们在循环的起始点相遇?
没有找到相关结果
已邀请:
19 个回复
傻寺俊擒
拟蓬
,我们最初距离循环
步。另外,我们可以说会议点距离周期开始是
步,并且在总共
步之后龟与野兔相遇。 必须满足以下两个条件:
第一个说乌龟移动
步,在这些
步骤中它首先进入循环。然后它经历周期
次以获得一些正数
。最后它超过了
节点,直到遇到野兔。 野兔也是如此。它移动了
步,在这些
步骤中它首先进入循环。然后它经过周期
次,得到一些正数
。最后它超过了
节点,直到遇到龟。 由于野兔的行进速度是乌龟的两倍,当它们到达会合点时,两者的时间都是恒定的。 因此,通过使用简单的速度,时间和距离关系,
在m,n,k,p,q中,前两个是给定列表的属性。如果我们可以证明k,q,p至少有一组值使这个方程成立,那么我们就证明假设是正确的。 一个这样的解决方案集如下:
我们可以验证这些值的工作原理如下:
对于这个集合,
是
当然,你应该看到这不一定是我可能的最小。换句话说,乌龟和兔子可能已经多次见过面了。然而,由于我们表明它们至少在某个时刻相遇,我们可以说假设是正确的。因此,如果我们将其中一个移动一步,而另一个移动一步两步,则必须满足。 现在我们可以进入算法的第二部分,即如何找到循环的开始。 循环开始 一旦乌龟和野兔见面,让我们把乌龟放回到清单的开头,并将野兔放在他们遇到的地方(距离循环开始的k步)。 假设是,如果我们让它们以相同的速度移动(两者都是1步),它们第一次再次相遇将是循环的开始。 让我们来证明这个假设。 让我们首先假设一些oracle告诉我们m是什么。 然后,如果我们让它们移动m + k步,那么乌龟必须到达它们最初遇到的点(距离循环开始k步 - 见图)。 以前我们展示了
。 由于m + k步长是周期长度n的倍数,因此,平均时间内的野兔将经历周期(q-2p)次并且将返回到相同点(距离周期开始k步)。 现在,不是让他们移动m + k步,如果我们让他们只移动m步,乌龟就会到达循环开始。野兔将完成(q-2p)轮换。由于它在循环开始前开始了k步,因此野兔必须在循环开始时到达。 结果,这解释了他们必须在第一次经过一些步骤后才开始在周期开始见面(这是第一次因为陆龟在m步之后到达周期而且它永远不会看到已经存在的野兔周期)。 现在我们知道我们需要移动它们直到它们相遇的步数变成从列表开头到循环开始的距离,m。当然,算法不需要知道m是什么。它会一次一步地移动乌龟和野兔,直到它们相遇。会合点必须是循环开始,步数必须是循环开始的距离(m)。假设我们知道列表的长度,我们还可以计算从列表长度中减去m的周期的长度。
鞋扣蚊冈借
抚驰
炬卤遁蝎变
攫怂绵十
癸痊醒
降女陷费券
步圈中有一个
步的头部开始。他们会在哪里见面?恰好在
步。当慢速跑步者已经
步时,快速跑步者将覆盖
步。 (即,
步骤即
步骤)。即
步(路径是圆形的,我们不关心它们相遇之后的轮数;我们只对它们相遇的位置感兴趣)。 现在,快速跑步者是如何首先获得
步骤的先机?因为慢跑者花了很多步才到达循环的开始。所以循环的开始是从头节点开始的k步。 注意:两个指针相遇的节点距离循环开始(循环内部)
步,并且头节点距离循环开始也是
步。因此,当我们从这些节点的机器人以相同的步长前进时,它们将在循环开始时相遇。 我相信这很简单。如果任何部分含糊不清,请告诉我。
钨蜡唤喉晤
是一个自然数(
)。但它可以用以下方式编写:
,其中
:
=循环长度
=常数
这意味着
。 例如:如果
和
=>
和
,因为
。 1所涵盖的距离是
。但与此同时,2覆盖
。这意味着当2在A中时它必须覆盖
。正如你所看到的,
是圈的数量,但是在那些圈后,2将远离A。所以,我们发现当1在A中时2是2.让我们称之为
,其中
。 现在,我们将问题缩小到一个圆圈。问题是“会面点在哪里?”。 C在哪里? 在每一步中,2减少距离1与
(比如米),因为1与
的距离越来越远,但同时2越接近1由
。 因此,交点将是1到2之间的距离为零。这意味着2减少了
距离。为了达到这个目的,1将
步,而2将
步。 因此,交点将远离A(顺时针)
,因为这是1所覆盖的距离,直到它遇到2. => C和A之间的距离是
,因为
和
。不要认为
,因为
距离不是一个微不足道的数学距离,它是A和C之间的步数(其中A是起点,C是终点)。 现在,让我们回到初始架构。 我们知道
和
。 我们可以采用2个新指针1'和1'',其中1'从头部开始(O),1'从交叉点(C)开始。 当1'从O变为A时,1'从C变为A并继续完成
圈。所以,交点是A.
梦话快家腹
闯舱酮
好吧,所以阶段2:慢需要N个步骤才能到达循环,此时快速(现在每步移动1步)处于(C-(N mod C)+ N)mod C = 0.所以它们相遇在第2阶段之后的周期开始时。
为了完整性,阶段3通过在循环中再次移动来计算循环长度:
蹄渭信妥扳
是从头部到周期开始的距离;
是循环中的节点数;
是较慢指针的速度;
是指针速度更快,例如。 2表示一次两个节点的步骤。 观察以下迭代:
从上面的示例数据中,我们可以很容易地发现,无论何时指针越快越慢,它们距离循环开始都是
步。要解决此问题,请将较快的指针放回头部并将其速度设置为较慢指针的速度。当它们再次相遇时,节点就是循环的开始。
枫湃揩乾纲
我们有2个指针A和B,A以1x速度运行,B以2x速度运行,两者都从头开始。 当A达到N [0]时,B应该已经在N [m]。 (注意:A使用m步到达N [0],B应该是m步) 然后,A运行k个步骤以碰撞到B, 即A为N [k],B为N [m + 2k] (注意:B应该从N [m]开始运行2k步) 分别为N [k]和N [m + 2k]的碰撞B,意味着 k = m + 2k,因此k = -m 因此,要从N [k]循环回N [0],我们需要更多步骤。 简单地说,我们只需要在找到碰撞节点后再运行几步。我们可以有一个从开始运行的指针和一个从碰撞节点运行的指针,它们将在m步之后在N [0]处相遇。 因此,伪代码如下:
稍惮
期差骇蓟
跳。让我们将圆圈的起点称为点
(在上限中 - 见上图)。我们还假设圆的总大小是N跳。 野兔的速度= 2 *龟的速度。那分别是
和
当乌龟到达
的圆圈开始时,野兔必须在图中的
处进一步
跳。 (因为野兔已经走过了两倍于乌龟的距离)。 因此,从X到Y顺时针的剩余弧长为
。这也恰好是野兔和乌龟之间能够相遇的相对距离。假设这个相对距离将在时间
,即见面时间内被覆盖。相对速度为
,即
。因此,使用相对距离=相对速度X时间,我们得到,
=
秒。因此,乌龟和兔子的交汇点将达到85英镑。 现在在
秒的时间和
的速度,早于
的乌龟将覆盖N-x跳跃到达会合点
。因此,这意味着会合点
从
逆时针方向
跳跃(=进一步暗示)=>顺时针方向从
到
剩余
距离。 但是
也是从链表开始到达
点的距离。 现在,我们不关心
对应的跳数。如果我们在LinkedList的开头放一只乌龟,在会合点
放一只乌龟,让它们跳/走,那么它们将在
点相遇,这是我们需要的点(或节点)。
荒劫娇噬
悸翠疮武昏
峨躬坎抬焚
现在,让兔子和乌龟从一开始就在时间之后相遇。 观察: 如果,乌龟行进的距离= v * t = x +(b-k)(比如说) 然后,野兔行进的距离= 2 * v * t = x +(b-k)+ b(因为野兔已经遍历了环状部分) 现在,会议时间是一样的。 => x + 2 * b - k = 2 *(x + b - k) => x = k 这当然意味着未循环的路径的长度与循环的起始点距离两者相遇的点的距离相同。
捻盒愧杯
用数学方式说明这一点:
所以他们将在时间t见面,这应该是周期长度的倍数。这意味着他们在一个地方见面,这是
。 所以现在回到这个问题,如果你从链表的起点移动一个指针,从交叉点移动另一个指针,在m步之后,我们将有野兔(在循环内移动)到达一个点,即
这只不过是循环的起点。所以我们可以看到,在m步后,它进入循环的开始,乌龟会在那里遇到它,因为它将从链表开始遍历m步。 作为旁注,我们也可以用这种方式计算它们交叉的时间:条件
告诉我们它们将在周期长度的倍数处相遇,并且t应该大于m,因为它们会遇到在周期中。因此,所花费的时间将等于大于m的n的第一个倍数。