【问题标题】:Question about logic of removing loop in linked list关于链表中去除循环的逻辑问题
【发布时间】:2020-02-01 15:49:44
【问题描述】:

下面是使用 Floyd 的慢速算法发现列表中存在循环后的代码。

我们如何确定 begin 和 tortoise 会在循环开始时相遇?

Node begin = head;
tortoise = tortoise.next;
while (begin != tortoise) {
    begin = begin.next;
    if (tortoise.next == begin) {        // Find the position of the loop and mark the node as null

        tortoise.next = null;
        return;
    }
    tortoise = tortoise.next;
}

任何帮助将不胜感激!

【问题讨论】:

  • 你问的是this吗?
  • @pablo 是的,但是解释不是很清楚。

标签: java algorithm floyd-cycle-finding


【解决方案1】:

让我们看看你发布的代码之前的第一部分。

考虑

  • 慢速指针(乌龟)和快速指针(野兔)。快速指针移动两次 慢速指针的速度,所以当慢速指针移动距离“d”时,快速移动了 距离“2d”。
  • 从起点到交点的长度为 x(参考图表)。
  • 它们在距离交叉点长度为 y 的随机点相遇(参见图表)。
  • 从交点到交点的长度为 z(参考图表)。
  • 循环长度为y+z;
  • 当慢与快相遇时。慢速已覆盖距离 x+y (例如 d)
  • fast 已覆盖距离 x+y+z+y (将是 2*d)

  • 2*d= x+2y+z

  • 2(x+y)= x+2y+z

  • 2x+2y=x+2y+z

  • x=z(已证明)

现在来看您发布的代码。

因为已经证明在第一个交汇点后 x 等于 z(假设兔子的速度是乌龟的两倍)然后从起点移动一个指针,从第一个交汇点移动一个指针到交点(即起点环形)。

【讨论】:

  • 我认为这种方法不适用于更长的长度。你能举出更长的循环或循环之前的任何其他例子吗?
  • 我的例子是关于变量的(我从未考虑过更长或更短的循环等)。对于任何给定的 x,y,z 值,它始终成立。请混合和匹配 x、y 和 z,然后请告诉我是否对您有意义。
  • 现在让第 X 天很长,循环很小 (x > y+z)。然后 z 将变为 n*z (其中 n 是循环遍历的次数)。直到从头开始的时间指针到达交点,循环内的指针将遍历n次循环,在循环的开始处与另一个指针相遇。我认为这是您的疑问,对吗?由于它是一个循环,因此您无需担心它被遍历了多少次,因为在一个圆圈中每个节点之间的距离不会发生变化。
【解决方案2】:

这个想法是两个指针以不同的速度移动。所以tortoisenext 可能会跳跃一个元素,而beginnext(我认为它通常被称为hare)可能会跳跃更多。 如果你同时增加它们并且有一个循环,一个会在某个时候赶上另一个。

【讨论】:

  • 我贴的代码sn-p是检测到循环后去循环的。我的怀疑是关于这段代码。如果你愿意,我可以粘贴其余的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 2012-02-24
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
相关资源
最近更新 更多