チェーンテーブルにループがあるかどうかを判断する方法


チェーンテーブルにループがあるかどうかを判断する方法
問題の説明
チェーンテーブルにループがあるかどうかをどのように判断し、ある場合は最初のループに入ったノードを返し、ない場合はnullを返します.
構想
チェーンテーブルにリングがない場合、チェーンテーブルを巡ると必ずチェーンテーブルの終点に遭遇することができます.チェーンテーブルにリングがあれば、チェーンテーブルを巡って永遠にリング内を回っていきます.具体的には以下の通りです.
​ 1.スナップポインタをfastとslowに設定します.最初に、slowとfastはチェーンテーブルのヘッダノードheadを指します.そしてslowは一歩移動するたびにfastは2部移動し、チェーンテーブルを巡ります.
​ 2.チェーンテーブルにループがない場合、fastポインタは移動中に必ずゴールに遭遇し、nullに直接戻り、チェーンテーブルにループがないことを示します.
​ 3.リングがあれば、fastとslowは必ずリングの中で出会う.出会った時、fastは再びheadの位置に戻り、slowは動かなかった.次に、fastポインタが一歩移動するたびに、slowは依然として一歩移動し、遍歴を続けます.
​ 4.fastとslowポインタは必ず再び出会い、最初のループに入ったノードで出会うことを証明します.
コード#コード#
public Node getLoopNode(Node head){
    if (head == null || head.next == null || head.next.next == null){
        return null;
    }
    Node n1 = head.next; //n1 -> slow
    Node n2 = head.next.next; // n2 -> fast
    while (n1 != n2){
        if (n2.next == null || n2.next.next == null){
            return null;
        }
        n2 = n2.next.next;
        n1 = n1.next;
    }
    n2 = head; // n2 -> walk again from head
    while (n1 != n2){
        n1 = n1.next;
        n2 = n2.next;
    }
    return n1;
}