141. 循環リンクリスト
この質問は依然として古典的な高速および低速ポインタ法を使用して行われます。速いポインタは毎回 2 歩進み、遅いポインタは 1 歩進みます。リングがあれば、リング内のどこかのノードで必ず出会います。思考には物理学の知識が関係しており、リングがあるとすれば、相対運動の過程において、それは遅いポインタが静止しているのと同じであり、速いポインタが一歩踏み出すたびに必ず出会うことになる。終わり。これは指輪があると判断するための条件でもあります。
ループがない場合、高速ポインタは移動中に必ず最後に null になります。これが非周期と判断するための条件です。
アルゴリズムコード
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast!=null&&fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
return true;
}
}
return false;
}
}
演算結果
142. 循環リンクリスト II
前問と比較すると、前問はリングの有無を判定するだけで済みますが、この質問も前問に基づいてリングに入り始めた連結リストの最初のノードを返します。リンクされたリストが非巡回の場合は null を返します。
ループがあると判断された場合、ヘッドノードへのポインタを追加するという考え方ですが、このとき、合流点を指すポインタと、新たに追加した(ヘッドノードを指す)2つのポインタは引き続き使用することになります。同じ「速度」で「会議」まで戻る(同じノードを指す)場合、このとき参照されるノードは、リンクリストがリングに入り始める最初のノードである。
アルゴリズムコード
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while(fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
ListNode node = head; //新加入一个指向头结点的指针
while(node != slow) {
node = node.next;
slow = slow.next;
}
return node; //返回slow也行
}
}
return null;
}
}
演算結果