【问题标题】:How loop detection algorithm in linked list works链表中的循环检测算法如何工作
【发布时间】:2026-01-18 02:55:02
【问题描述】:

我知道这可以通过使用两个指针来完成,一个慢一个快。但是我仍然不清楚的是,如果有一个循环,那么我们如何确定慢速和快速指针在一个点上重叠。我想在某些情况下它们无限循环而不重叠。两者必须重叠的周期数是否有任何方程式或上限。

【问题讨论】:

  • 举一个简单的例子并调试(dryrun)它。你我们找到了。

标签: algorithm singly-linked-list


【解决方案1】:

忘记链表。并尝试假设您和您的伙伴正在环形赛道上进行比赛。但是他比你快2倍。当你跑完半圈时,你的好友会跑完一圈,当你跑完第一圈时,你的好友会比你快 2 倍。

现在将圆圈替换为代表链表节点的圆点。

但是假设你没有循环列表,那么你跑得更快的伙伴会到达最后一个节点并完成比赛。

【讨论】:

  • 但是如果你的伙伴每次都跳过两个点,他可能会超过你,而你却不会同时击中同一个点。你对此有什么解释吗?
  • @MarkRansom:你先移动,一个点。然后你的伙伴移动 2 个点。他不能跳过你现在所在的点,因为那需要他在你之前所在的点上,在这种情况下,你已经在同一个点上。 (当然,这是实际的链表,而不是这里提出的连续赛道。)
  • @rici 这意味着问题中的描述不正确,它不是“一慢一快” - 它是“一+1和一+2”。任意速度都行不通。我希望 Ritesh 能回来改进答案。
  • @MarkRansom:很公平。 Ritesh 在连续情况下的解释是正确的:必须有两个跑步者并排的时刻。只要尾部和循环都是离散步长的整数倍,用离散步代替连续运动不会改变这一事实,在这种情况下,你们两个将在离散步上对应。因此,任意速度都可以,但任意长度则不行:点的划分需要是整数。
【解决方案2】:

考虑两个指针。 P1 和 P2。 (龟兔赛跑)

P1  P2  Delta
1   2   1
2   4   2
3   6   3
4   8   4
5   10  5
6   12  6

两者之间的距离每一步增加1。最终(在一个循环中)他们会相遇。

【讨论】:

    【解决方案3】:

    这个想法是慢(乌龟)指针每一步前进 1 项,而快速(野兔)指针每一步前进 2 项。

    当兔子非常靠近乌龟时(在 X 处),假设它落后 2 个项目 (X - 2).. 下一步:

    野兔位置:X
    龟位:X + 1

    现在兔子只落后 1 件,下一步:

    野兔位置:X + 2
    龟位:X + 2

    他们相遇了。如您所见,如果它们之间的距离是 2 个项目,它们最终会相遇,如果距离是 1 个项目(如 2 个项目之后的下一步),它们将在下一步相遇。

    兔子总是快 1 步,所以它不能“跳过”。

    【讨论】: