Algorithm 在链表中查找循环的起始节点?

Algorithm 在链表中查找循环的起始节点?,algorithm,data-structures,linked-list,Algorithm,Data Structures,Linked List,如何在给定的链表中找到循环的起始节点?让我们称之为周期点 到目前为止,我已经了解了以下内容(使用慢速/快速指针): 假设列表有一个大小为k 慢行慢步 快速移动2k步 快速是(2k-k)=kstepsforwardof slow 慢是循环的开始;也称为循环点 快速是(循环长度-k)步数在循环点之后或慢速指针在该点 每慢走1步,快走2步,慢走1步 因此,需要快速的(LOOP_LENGTH-k)步骤才能满足慢速和碰撞的要求 这是我不明白的步骤: 在此碰撞点,两个节点都将从循环前面开始k步。 找到冲突点

如何在给定的链表中找到循环的起始节点?让我们称之为周期点

到目前为止,我已经了解了以下内容(使用慢速/快速指针):

  • 假设列表有一个大小为
    k
  • 慢行慢步
  • 快速移动2k步
  • 快速是(2k-k)=
    k
    steps
    forward
    of slow
  • 慢是循环的开始;也称为循环点
  • 快速是
    (循环长度-k)
    步数
    循环点之后
    或慢速指针在该点
  • 每慢走1步,快走2步,慢走1步
  • 因此,需要快速的
    (LOOP_LENGTH-k)
    步骤才能满足慢速和碰撞的要求
  • 这是我不明白的步骤: 在此碰撞点,两个节点都将从循环前面开始
    k
    步。
  • 找到冲突点后,将一个指针移动到列表的开头
  • 现在以1步/圈的速度移动两个指针,直到碰撞。它们相遇的节点是循环的开始,所以是循环点
  • 有人能给我解释一下第九步和之后的步骤吗

    谢谢

    编辑


    我想指出的一点是,一旦进入循环,快速指针永远不会超过慢速指针。它们会相撞。原因如下:慢在i,快在i-1。当它们移动时,slow=>i+1和fast也将位于i+1,因此会发生碰撞。或者,慢在i,快在i-2。下一步,慢->i+1;快:我。下一步,慢->i+2,快:i+2,然后再次碰撞。如此之快永远无法超越慢速,只能在环路内碰撞一次

    嗯。。这种问题很难解释,除非你是面对面交谈。我要试一试

    首先在步骤6中:我认为快速指针应该距离圆点
    k
    距离

    但别再提这些了。我们现在有两辆车。速度是慢车速度两倍的快车

    假设快车在距离圆点
    k
    距离处以圆形轨道启动

    慢车从圆点开始

    现在我说的是,两辆车将在圆点之前的
    k
    距离处相遇

    为什么??因为一开始,快车与圆点的距离为
    k
    。第一次完成圆圈时,快车将行驶
    n
    距离。现在,快车又在离圆点k距离处。但是慢车距离圆圈点的距离为
    n/2

    现在,快车必须再行驶
    n-2k
    距离,才能到达圆点之前的
    k
    距离。慢车必须行驶
    n/2-k=(n-2k)/2
    距离才能到达起点前的
    k
    距离
    正好是快车行驶路径距离的一半
    。快车的速度是慢车的两倍


    所以很明显,它们将在距离圆点之前的
    k
    距离处相遇。

    6。如果是错误的,则快速指针仍与当时处于循环点的慢速指针相距k步;但最好在前方使用,或在后方使用,而不是在远处使用。另外,
    k
    可能更小、更大或等于
    循环长度

    因此,当到达循环点时,快速指针比慢速指针提前
    k
    步,根据您的假设,循环点在开始后
    k
    步。现在,在循环上测量时,快速指针位于循环点前面的
    k%loop\u length
    步数处。对吗?如果
    k=some\n*loop\u length+r
    ,则快速指针位于循环点前面的
    r
    步数,也就是说,
    r:=k%loop\u length
    步数

    但这意味着慢指针在循环中比快指针提前
    loop\u length-r
    步数。这毕竟是一个循环。因此,在
    循环长度-r
    附加步骤之后,快速指针将捕捉到慢速指针。每走一步,慢指针就会移开,快指针就会移进两步

    所以我们不知道
    k
    ,我们不知道
    loop\u length
    r
    ,我们只知道
    m=k+loop\u length-r=some\n*loop\u length+r+loop\u length-r=(some\n+1)*loop\u length
    。两个指针汇合点之前的总步数
    m
    ,是循环长度的倍数

    现在我们重新开始,在开始处有一个新指针,在慢指针遇到快指针时,
    m
    在新指针前面一步。我们以相同的速度移动新指针和慢速指针,每次移动1步,在循环点处移动,因为当新指针到达循环点时,第二个指针仍然向前移动
    m
    步,也就是说,
    m%loop\u length==0
    沿着循环向前移动。这样我们就可以知道什么是
    k
    (我们一直在计算我们的步数),以及循环点

    我们再沿着循环走一次,直到两个循环再相遇一次,就可以找到
    loop\u length

    • 另见:

    你能解释这个关系吗
    m=k+loop\u length-r=some\n*loop\u length+r+loop\u length-r=(some\n+1)*loop\u length
    ?我刚刚替换了这些值:两个指针相交前的总步骤数是多少?我们说我们有
    k
    步数直到循环点;当slow位于
    k
    时,fast位于slow之前
    r=k%loop\u length
    ;i、 e.慢是快之前的
    loop\u length-r
    ,因为慢站在循环点,如果我们把从慢到快的距离加起来,然后从快到快,我们得到
    loop\u length
    。这就是循环的意思。和
    r=