我阅读了问题的解决方案如何检查链表是否为循环。
for:a-> b-> c-> a:TRUE
for:a-> b-> c-> null:FALSE
该解决方案使用更快更慢的指针。每次跳过2个单元的速度越快,每次跳过一个单元越慢。如果更快的指针达到NULL,那么它是假的,如果较慢的指针遇到的速度比它的真实速度快。
我不明白是谁同意这两个指针会相遇?如果列表是1000万个单元格,你怎么能确定它们会满足?如果两者都在名单上无休止地传递并且从未见过会怎么样?
我知道这个解决方案是正确的,但我看到的地方只有解释代码的作用或示例..我无处可以找到一个证据,证明这实际上适用于所有情况。
答案 0 :(得分:2)
关键的观察是,在每一步之后,两个指针之间的距离增加一个(一个指针移动一步,另一个指针移动两步)。
如果列表是循环的,并且循环是n
个元素长,则当(1)它们都进入循环时,两个指针保证指向相同的元素,(2)两者之间的距离它们是n
的倍数。
n
的循环中,n
元素向前(或向后)移动就是无操作。从元素x
开始并执行n
步骤将指针返回到元素x
。从最初的观察中我们知道,两个指针之间的距离在每一步中都增加了一个。在某些时候,两个指针之间的距离是n
的倍数,在这一点上指针指向同一个元素。答案 1 :(得分:1)
如果循环列表有10,000,000个条目,并且一个指针是超过另一个指针的10,000,000个位置,则它们是相等的。
您描述的算法还将发现列表是ρ形还是圆形,因为两个指针最终都会到达圆形区域。如果唯一的可能性是一个结束的列表和一个圆形的列表,那么你可以沿列表步进一个指针,直到它达到null或它等于头部。
这三个形状( - ,o和ρ)是(非空)单链表可以拥有的唯一三种形状:如果你从头开始并迭代,要么你将达到目的,要么你将到达您已访问过的元素。如果你重新审视头部,你会得到一个o形状,如果你再次访问其他地方,你会得到一个ρ形状。因此,能够处理所有三种形状可确保您的算法完成。
(在上面,我已经将“列表”定义为您可以从头部开始迭代的节点集合。这些节点可能是更大,更复杂的图形的一部分。)