标签: floyd-cycle-finding

Floyd用于在链表中查找循环的算法,如何证明它将始终有效

我理解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

2
推荐指数
1
解决办法
2526
查看次数

为什么弗洛伊德的循环查找算法对于某些指针增量速度会失败?

考虑以下链接列表:

1->2->3->4->5->6->7->8->9->4->...->9->4.....
Run Code Online (Sandbox Code Playgroud)

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

[4->5->6->7->8->9->4]
Run Code Online (Sandbox Code Playgroud)

在白板上绘制链接列表,我尝试手动解决不同的指针步骤,以查看指针如何移动 -

(slow_pointer_increment, fast_pointer_increment)

因此,针对不同情况的指针如下:

(1,2), (2,3), (1,3)
Run Code Online (Sandbox Code Playgroud)

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

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

algorithm linked-list floyd-cycle-finding cycle-detection

1
推荐指数
1
解决办法
895
查看次数

Ruby 中哈希中的循环检测

通过哈希,我有一个“工作”列表,每个工作都有一个 id 和一个 Parent。具有父级的作业只有在其父级执行完毕后才能执行。我如何检测依赖循环?

数据集如下图所示:

jobs = [
  {:id => 1,  :title => "a",  :pid => nil},
  {:id => 2,  :title => "b",  :pid => 3},
  {:id => 3,  :title => "c",  :pid => 6},
  {:id => 4,  :title => "d",  :pid => 1},
  {:id => 5,  :title => "e",  :pid => nil},
  {:id => 6,  :title => "f",  :pid => 2},
]
Run Code Online (Sandbox Code Playgroud)

'id' 的顺序是: 1 > 2 > 3 > 6 > 2 > 3 > 6.... 等等

floyd-cycle-finding

1
推荐指数
1
解决办法
623
查看次数

循环检测算法

说我有一个函数f:

f(0) = 0
f(i) = (i - 1) % 4
Run Code Online (Sandbox Code Playgroud)

F(0..12):

0 0 1 2 3 0 1 2 3 0 1 2 3
Run Code Online (Sandbox Code Playgroud)

我想找到循环开始和循环长度,分别为1和4.乌龟和野兔算法适用于迭代函数,但我没有迭代函数.是否有其他算法可以使用非迭代函数,或者可以为此修改龟和野兔算法?

编辑:

使用Jason S的答案,我设法提出了这个,这似乎是有效的:

public static Tuple<int, int> ModifiedTortoiseHare(Func<int, int> f, int x0 = 0, int checks = 4)
{
    for (; ; x0++)
    {
        int lam = 0, tortoise, hare;

        do
        {
            lam++;
            tortoise = f(x0 + lam);
            hare = f(x0 + 2 * lam);
        } while (tortoise != hare);

        int mu = -1; …
Run Code Online (Sandbox Code Playgroud)

algorithm function cycle detection floyd-cycle-finding

0
推荐指数
1
解决办法
1752
查看次数

使用C#在LinkedList中进行循环检测

在访谈问题中,"实现一种检测循环存在的算法".例如,链表有一个循环,如:

0--->1---->2---->3---->4---->5---->6
                 ?                 |
                 |                 ?
                11<—-22<—-12<—-9<—-8
Run Code Online (Sandbox Code Playgroud)

使用Floyd的循环检测,可以通过使用快速和慢速指针来解决此问题.我应该尝试比较

一个.链接的节点值,即

if (fast.data == slow.data) 
    break;
Run Code Online (Sandbox Code Playgroud)

快速和慢速的类型 Link

class Link
{
    int IData {get; set;}
    Link Next {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

要么

他们是否指向相同的参考,即if (fast == slow)

谢谢.

c# linked-list floyd-cycle-finding

0
推荐指数
1
解决办法
4594
查看次数