链表中的循环检测:穷举理论

时间:2011-12-17 07:16:38

标签: algorithm data-structures linked-list graph-theory

这不是使用famous Hare和Tortoise方法检测链表中的循环的问题。

在野兔& Tortoise方法我们有以1x和2x速度运行的指针,以确定它们是否满足,并且我确信它是最有效的方式,并且该类型的搜索顺序是O(n)。

问题是我必须提出一个证据(证明或反驳),当移动速度是Ax(A倍x)和Bx(B乘x)并且A是A时,两个指针总是可以相遇不等于B.其中A和B是在链表上运行的两个随机整数,并且存在循环。

我最近参加的一次采访中提到了这一点,我无法全面向自己证明以上是否可行。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:10)

假设有一个循环,比如长度L

简易案例

为了使其更容易,首先考虑两个粒子同时完整循环的情况。对于某些正整数n*A = n*B (mod L),这些粒子在n处于同一位置,这是直到它们再次相遇的步数。取n=L给出一个解决方案(尽管可能有一个较小的解决方案)。因此,在L单位时间之后,粒子A已经使A绕着循环返回到开头并且粒子B已经B绕行循环回到开头,他们愉快地碰撞。

一般情况

现在当他们不同时进入循环时会发生什么?让A成为较慢的粒子,即A<B,并假设A在时间m进入循环,让我们调用A进入的位置循环0(因为它们在循环中,它们永远不会离开它,所以我只是通过减去A*m来重命名位置,距离A在{{1}之后移动了时间单位)。那么,那时m已经位于B位置(m*(B-A)时间单位为m之后的真实位置,因此重命名的位置为B*m) 。然后,我们需要显示B*m-A*m时间为n。也就是说,我们需要一个模块化方程的解决方案

n*A = n*B+m*(B-A) (mod L)

(n+m) * (A-B) = 0 (mod L) n = k*L-m足够大,k可以解决问题,但可能会有更小的解决方案。

因此,是的,他们总是相遇。

答案 1 :(得分:1)

如果你的两个步长有一个共同因子x:假设步长是Ax和Bx,那么只考虑从原始序列获取的序列并取每个第x个元素。当且仅当原始序列发生时,这个新序列才有一个循环,并且在其上采用大小为A和B的步骤相当于在原始序列上采用大小为Ax和Bx的步骤。

这种减少意味着当A和B是互质的时候证明算法是有效的就足够了。

答案 2 :(得分:-1)

假设是错误的。例如,如果两个指针都是偶数大小的跳跃,那么循环的大小也是均匀的,指针之间的距离是奇数,它们永远不会相遇。

UPD这显然是不可能的情况。因为两个指针从同一点开始,它们之间的距离将始终是均匀的。