所以我最近遇到了算法来确定链表中是否存在循环。代码如下:
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"这样上面的等式是可以解决的?
答案 0 :(得分:0)
你走在正确的轨道上!提示: a 迭代后你的公式会发生什么?
答案 1 :(得分:0)
假设两个指针都在循环内的同一点开始(这不算作会议)
2t = t (a)
=> 2t - t = 0 (a)
=> t = 0 (a)
这意味着在t = a * k时,两个指针在经过的时间是周期长度的倍数之后将在起点处相遇。
对于所有a >= 2
都是如此,因为当所有k*a
的时间等于k>1
时,慢指针精确地运行k个周期,而快速指针运行速度快两倍,所以它运行2k个周期,但它们仍然在同一点上相遇,这是起点。