循環リンクリストII
トピック
リンクリストを指定して、リンクリストがループに入り始める最初のノードを返します。リンクリストにリングがない場合は、nullが返されます。
特定のリンクリスト内のリングを表すために、整数posを使用して、リンクリストの終わりがリンクリストに接続されている位置を示します(インデックスは0から始まります)。posが-1の場合、リンクリストにリングはありません。posはリングを識別するためにのみ使用され、パラメーターとして関数に渡されないことに注意してください。
注:指定されたリンクリストを変更することは許可されていません。
上級:
O(1)空間を使用してこの問題を解決できますか?
入力:head = [3,2,0、-4]、pos = 1
出力:インデックス1のリンクリストノードを返します
説明:リンクリストにリングがあり、そのテールは2番目のノードに接続されています。
入力:head = [1,2]、pos = 0
出力:インデックス0のリンクリストノードを返します。
説明:リンクリストに、テールが最初のノードに接続されているリングがあります。
入力:head = [1]、pos = -1
出力:nullを返します
説明:リンクリストにリングがありません。
促す:
リンクリスト内のノード数の範囲は[
0、104 ] -105 <= Node.val <= 105
の範囲です。posの値は-1またはリンクリスト内の有効なインデックスです。
アイデア1:ハッシュテーブル
保存するノードがすでにハッシュテーブルにある場合は、ノードに戻るだけです。
public class Solution {
public ListNode detectCycle(ListNode head) {
HashSet<ListNode> hashSet =new HashSet<ListNode>();
while(head != null){
if(!hashSet.add(head)){
return head;
}
head = head.next;
}
return null;
}
}
アイデア2:速いポインターと遅いポインター
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
ListNode slow = head,fast = head;
do{
if(fast==null|| fast.next==null) return null;
fast =fast.next.next;
slow = slow.next;
}while(fast != slow);
//当fast与slow重合时,将fast移动到head,此时fast到入环点的距离与slow到入环点的距离是一样的。
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}