【问题标题】:Why does Floyd's cycle finding algorithm fail for certain pointer increment speeds?为什么 Floyd 的循环查找算法对于某些指针增量速度会失败?
【发布时间】:2017-11-24 21:20:28
【问题描述】:

考虑以下链表:

1->2->3->4->5->6->7->8->9->4->...->9->4.....

上面的列表有一个循环如下:

[4->5->6->7->8->9->4]

在白板上画链表,我尝试手动求解不同的指针步骤,看看指针如何移动 -

(slow_pointer_increment, fast_pointer_increment)

所以,针对不同情况的指针如下:

(1,2), (2,3), (1,3)

前两对增量 - (1,2) 和 (2,3) 工作正常,但是当我使用 (1,3) 对时,算法似乎不适用于这对。有没有规定我们需要增加多少步数才能使该算法成立?

虽然我为较慢和较快的指针搜索了各种增量步骤,但到目前为止,我还没有找到一个相关的答案来说明为什么它不适用于此列表中的增量 (1,3)。

【问题讨论】:

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


    【解决方案1】:

    Bernhard Barker 的解释恰到好处。 我只是添加它。

    为什么指针之间的速度差和循环长度应该是 互质数?

    假设指针(比如v)和周期长度(比如L)之间的速度差异不是互质的。 所以存在一个大于 1 的 GCD(v,L)(比如G)。

    因此,我们有

    • v=指针之间的速度差异
    • L=循环长度(即循环中的节点数)
    • G=GCD(v,L)

    由于我们只考虑相对位置,基本上slow 是静止的,fast 以相对速度v 移动。 让fast 位于循环中的某个节点。

    由于GL 的除数,我们可以将周期划分为总帐部分。从fast所在的位置开始划分。

    现在,vG 的倍数(比如v=nG)。 每次fast 指针移动时,它都会跳过n 部分。因此,在每个部分中,指针都到达单个节点(基本上是一个部分的最后一个节点)。每次fast 指针都会落在每个部分的结束节点。参考下图

    Example image

    正如 Bernhard 上面提到的,我们需要回答的问题是 我们能以某种速度到达每个位置吗?

    如果我们有一个现有的GCD,答案是。正如我们所见,fast 指针只会覆盖每个部分的最后一个节点。

    【讨论】:

      【解决方案2】:

      只有当指针增量和循环长度之间的差是互质数(即它们的最大公约数必须是 1)时,该算法才能保证在任何位置找到一个循环。

      对于一般情况,这意味着增量之间的差必须为 1(因为这是唯一与所有其他正整数互质的正整数)。

      对于(1,3),差是3-1=2,循环长度是222不是互质的,因此算法不能保证找到循环。


      理解这一点的关键是,至少为了检查指针是否相遇,循环中慢速和快速指针的位置仅相对于彼此有关。也就是说,这两者可以认为是等价的:(两者的差为1)

      slow fast             slow fast
         ↓ ↓                   ↓ ↓
       0→1→2→3→4→5→0     0→1→2→3→4→5→0
      

      所以我们可以根据slow 保持不变的位置和fastfastIncrement-slowIncrement 的增量移动来考虑这一点,此时问题就变成了:

      从任何位置开始,我们能否以某种速度(模周期长度)移动到达特定位置?

      或者,更一般地说:

      我们能否以某种速度(模周期长度)移动到每个位置?

      只有当速度和周期长度互质时才会如此。

      例如看速度为4,循环长度为6——从0开始,我们访问:
      0, 4, 8%6=2, 6%6=0, 4, 2, 0, ... - GCD(4,6) = 2,我们只能访问每隔一个元素.
      要查看实际情况,请考虑上面给出的示例的 (1,5) (difference = 4) 增量,并看到指针永远不会相遇。


      我应该指出,至少据我所知,(1,2) 增量被认为是算法的基本部分。

      使用不同的增量(根据上述约束)可能会起作用,但它会远离“官方”算法并且会涉及更多工作(因为指向链表的指针必须迭代地递增,您可以'不要在一个步骤中将其增加超过 1)对于一般情况没有任何明显的优势。

      【讨论】:

        猜你喜欢
        • 2015-10-02
        • 2012-08-26
        • 1970-01-01
        • 2015-01-31
        • 2017-01-19
        • 2016-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多