問題の説明
特定のリンクリストについて、リングのエントリノードを返します。リングがない場合は、nullを返して
展開
します。余分なスペースを使用しないソリューションを提供できますか?
説明の入力:
リンクリストを入力します
出力の説明:
出力リングのエントリノード
例
例1
入力
{-3、-2、-1,0,1,2,3,4,0(円形)}
出力
{0}
ソリューション
分析
- ハッシュテーブル(余分なスペースを使用):レコードをハッシュテーブルにトラバースして、循環リンクリストのエントリを検索します。
時間の責任:O(n)
スペースの責任:O(n) - 高速および低速ポインタ(余分なスペースを使用しない):高速および低速ポインタによって実現されます。これについては、以下で詳しく説明します。
デモンストレーションプロセス:(高速ポインタと低速ポインタの開始点が0で
あることに注意してください)リンクリストにリングがあり、リングの長さがbで、非リングの長さがb1であるとし
ます。高速と低速の移動距離。ここでは、n周後にミートしたと仮定し
ます。
高速= 2低速高速=低速+ nb
式のスケールは等しい:2
低速=低速+ nb取得
:
低速= nb
高速= 2nb
------ -------------- --------------
2.入口に到達するために何ステップかかることができますか?
enter = a + nb
---- ------------------- -----------
3。高速ポインタと低速
高速の2回目の遭遇= 0;
低速= nb;両方とも
高速そして遅いポインタは一歩進んだ:
速い= a;
遅い= a + nbthis
彼らが入り口で会ったとき
方法
- Hasayテーブルを通して。
- 下の写真はスピードポインターを通してデモンストレーションプロセスであり、写真はリコウの写真を採用しています
コード
// 思路1
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode pos = head;
Set<ListNode> visited = new HashSet<ListNode>();
while (pos != null) {
if (visited.contains(pos)) {
return pos;
} else {
visited.add(pos);
}
pos = pos.next;
}
return null;
}
}
// 思路2
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (true) {
if (fast == null || fast.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
break;
}
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
テストしたい場合は、Niuke.comのリンクに直接アクセスしてテストを行うことができます