【问题标题】:Detect First Node in the Cycle in Linked List检测链表循环中的第一个节点
【发布时间】:2016-08-10 08:16:26
【问题描述】:

最近,我已经完成了用于检测循环中第一个节点的算法,如下所述:-

注意:此声明摘自网站:-

http://javabypatel.blogspot.in/2015/12/detect-loop-in-linked-list.html

现在的重点是,我们将如何知道循环的起始节点。
步骤 1:找到循环后,两个指针都指向在汇合点的公共节点 内循环,
第 2 步:现在,将其中的一个指针(比如乌龟)移动到列表的头部,保持兔子 指针位于与循环内的交汇点相同的位置。
第 3 步: 开始一次将两个指针移动一个节点。他们相遇的地方是开始 循环/循环的节点。

让我们考虑下图中的案例2:-

http://4.bp.blogspot.com/-79s5PBIexDE/Vmac8UlposI/AAAAAAAAAvQ/ejHRpGv_OLY/s1600/loop-in-linked-list-example.png

在应用所有步骤时,在案例 2 中,我陷入了 步骤 3

“以下是兔龟算法针对案例 2 的演算。”

更快 - 1 更慢 - 1
更快 - 5 更慢 - 20
更快 - 22 更慢 - 5
更快 - 20 更慢 - 18
更快 - 18 更慢 - 22
更快 - 1 更慢 - 1 - 两个指针在这里相遇..

因此,按照第 2 步,我将 Faster Pointer 保持原样,并将 Slow Pointer 移动到 1(这是列表的头部)。

因此,按照第 3 步,我将每个指针一一递增。

由于它们都在“1”中,将每个指针移动一个,永远不会结束,它会一直移动。

Q1.请问,我在第 3 步中是否理解错了什么?

Q2.我可以假设循环结束的节点是循环中的第一个节点吗?

【问题讨论】:

标签: algorithm data-structures linked-list


【解决方案1】:

直到最后一步,您似乎一直正确地跟踪给定的算法。不过,在最后一步,我认为您将术语 列表头 误认为是指向列表第一个元素的指针。因此,您可能已经推断出循环永远不会结束,因为两个指针将以相同的速度移动,并且一个会领先另一个 1。然而,我相信 列表的头部 被使用了引用列表中的第一个元素,而不是指向第一个元素的指针。

顺便说一句,我认为您的困惑并非源于您所犯的错误,而是您在问题中提供的伪代码存在歧义。即使您没有误解列表的头部,您也会执行一次伪代码的Step 3,并得出结论,指针将在标签为 20 的节点处相遇。(即列表的第一个节点之后的那个)所以,我认为步骤 3 可以使用以下说明。

第 3 步: 当兔子和乌龟位于不同的单元格时,一次将两个指针移动一个节点。

这样更正,如果遇到像你提供的case 2这样的情况,将其中一个指针移动到列表的开头后,将不满足迭代的条件,因为指针已经见面了。 (由于循环的开始在列表的开头)

尽管您最初的 Q2 很不清楚,但让我根据您对它的澄清来回答它,就像我的回答一样。

在您提供的链接中,显示在您提供的伪代码的第 1 步之后,相遇点 M 野兔和乌龟指针相遇与循环开始的确切距离为列表的第一个元素有。 (即上图中的距离 p 和 r 相等)因此,如果一个指针位于列表的开头,而另一个保持在它们的交点处,如果两者都移动 1,只要它们不在列表的同一个节点,是的,你可以假设它们相遇的地方将是列表中循环的开始,如果这样的循环曾经存在的话。

【讨论】:

  • 您好,我对 Q2 的理解是否正确。一些建议请。谢谢。
  • 您能否澄清您在 Q2 中指的是哪个循环?是第一个循环,兔子和乌龟都走 1,还是你提供的伪代码的 步骤 3 中描述的循环,兔子和乌龟都走 1?
  • 在此,我指的是“乌龟”循环。 1. 一般来说,通过查看任何具有这样循环的问题,我是否可以得出结论,循环中的第一个节点是乌龟循环的结束? 2.特此,我不能拿野兔指针,因为它可能会跳到外面或里面或正好在“1”上吗?...谢谢..
  • 更新了我的答案,以澄清您在最新评论中提出的问题 #1 的答案。至于您在同一评论中的问题 #2,是否将兔子或乌龟指针移动到列表的开头没有任何区别。在最后一个循环中,兔子和乌龟都移动了 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 2011-12-04
相关资源
最近更新 更多