【发布时间】:2016-10-06 00:50:02
【问题描述】:
所以最近遇到了判断链表中是否存在循环的算法。代码如下:
public boolean hasCycle(ListNode head) {
if (head == null) {
return false;
}
ListNode fast = head;
ListNode slow = head;
while (fast != null) {
if (fast.next == null) {
return false;
}
if (fast.next == slow) {
return true;
}
fast = fast.next.next;
slow = slow.next;
}
return false;
}
在试图证明这个算法的正确性时,我想到了一个想法: 假设循环的周长是“a”,两个指针相遇之前经过的时间是“t”。由于“快”节点的移动速度是“慢”节点的两倍,我们可以得到数学关系:
2t mod a = t mod a
现在“a”是一个常数,代表周长,“t”可以是1,2,3....那么,我如何证明无论“a”是什么值,我们总能找到一个“ t" 这样上面的方程是可解的?
【问题讨论】:
-
如果循环不是从第一个节点开始,等式是否正确?例如:1->2, 2->3, 3->4, 4->5, 5->3, 循环 = {3,4,5,3}
-
任何
t = 0 mod a解决2t = t mod a。您还需要t >= s,其中需要s步骤才能进入循环。 -
@MattTimmermans 嗯...我想了一会儿之后可能是一样的:2t -s = t-s (a) 所以 2t = t (a),但不确定
-
@shole,你需要这两个条件。如果进入一个长度为 10 的循环需要 13 步,那么指针将在 t=20 和 t=30 处相遇,而不是 t=10
标签: algorithm loops linked-list