确定循环是否存在于链表

时间:2016-10-06 00:50:02

标签: algorithm loops linked-list

所以我最近遇到了算法来确定链表中是否存在循环。代码如下:

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"这样上面的等式是可以解决的?

2 个答案:

答案 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个周期,但它们仍然在同一点上相遇,这是起点。