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