【问题标题】:Floyd's algorithm for finding a cycle in a linkedlist, how to prove that it will always work弗洛伊德在链表中寻找循环的算法,如何证明它永远有效
【发布时间】:2013-11-25 02:23:39
【问题描述】:

我了解 Floyd 循环检测算法的概念。得出的结论是,如果乌龟的行进速度是兔子的两倍,并且如果乌龟在一个循环中领先 k 米,那么乌龟和兔子将在循环之前遇到 k 米。

在单链表的情况下,指针 A 的移动速度是指针 B 的两倍。这意味着如果指针 B 需要 k 步才能到达循环的入口点(我们还不知道它在哪里),指针 A 将在循环内具有 k 个节点的领先位置。因此,两个指针将在循环的入口点之前遇到 k 个节点。因此,如果我们将指针 B 移回头指针并将指针 A 保持在交汇点(现在两个指针都离入口点有 k 个节点),并以相同的速度移动,它们将在入口点相遇循环。

您如何证明该算法在以下边界情况下有效?

  1. 最后一个节点循环回头部的链表。在这种情况下,起始值 k 是多少?
  2. 一个超长的链表,1000个节点,最后有一个小循环,3个节点。指针 A 将领先 1000,这意味着当指针 B 到达循环的入口点时,A 已经循环了很多次。
  3. 如果有 1 个节点的循环怎么办?

这不是家庭作业。一位面试官告诉我,如果我有一个小循环,这个算法将无法工作。他没有解释原因。

【问题讨论】:

  • 如果面试官真的这么说,那他就错了。

标签: algorithm linked-list floyd-cycle-finding


【解决方案1】:

请考虑一下:n 移动后,您可以确定两个指针都在循环中,或者其中一些指针已经结束。在接下来的n 移动中,您可以确定 A 和 B 会在某个点相遇,因为循环的大小为 n,并且每走一步,它们之间的差异就会减少 1。

【讨论】:

    【解决方案2】:

    很明显,如果有一个,两个指针最终都会到达循环。让我们假设,循环的长度为 N。我们可以在循环中以 N 为模计算位置。

    现在说指针 A 在位置 a,指针 B 在位置 b。经过 s 步后,A 将在 a+2s mod N 处,B 将在 b+s mod N 处。对于要相遇的两个指针,我们必须有

    a+2s = b+s (mod N)
    a+s = b (mod N)
    s = b - a (mod N)
    

    所以在 b - a (mod N) 步之后,两个指针会相遇。

    【讨论】:

    • (mod N) 表示,所有计算都在同余类 mod N 的环中完成。“mod”不是运算符。
    【解决方案3】:

    当然,它适用于一个小循环。考虑两个节点的循环。那就是:

    A => B => C => B
    

    所以龟兔赛跑从A开始。下表显示了发生的情况:

    Tortoise  Hare
       A       A
       C       B
       C       C
    

    当只有两个节点时,乌龟总是在它开始的地方结束。因此,当兔子每次移动一个节点并最终赶上时,乌龟将基本上保持静止。

    顺便说一句,当您有一个只有一个节点的循环时,也会发生同样的事情。也就是说,当一个节点在自身上循环时。

    亨利的回答给出了数学证明。

    【讨论】:

    • 我觉得你桌子上的龟兔赛跑应该是兔兔兔(兔兔跑得更快,但不在你的桌子上)。
    猜你喜欢
    • 2011-04-22
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    相关资源
    最近更新 更多