トピック:
リンク リストのヘッド ノードを指定してhead
、リンク リストにリングがあるかどうかを判断します。
ポインターを継続的に追跡することによって再度到達できるリンク リスト内のノードがある場合next
、リンク リスト内にサイクルが存在します。指定されたリンク リスト内のリングを表すために、評価システムは内部で整数を使用して、pos
リンク リストの末尾がリンク リストに接続される位置を示します (インデックスは 0 から始まります)。注:pos
パラメータとしては渡されません 。リンクリストの実態を特定するためだけに。
リンクされたリストにサイクルがあるかどうかを 返しますtrue
。それ以外の場合は、 を返しますfalse
。
例:
1.
入力: head = [3,2,0,-4]、pos = 1 出力: true 説明:リンクされたリストに、末尾が 2 番目のノードに接続されているリングがあります。
2.
入力: head = [1,2]、pos = 0 出力: true 説明:リンクされたリスト内にリングがあり、その末尾が最初のノードに接続されています。
3.
入力: head = [1]、pos = -1 出力: false 説明:リンクされたリストに循環がありません。
アイデア:
高速ポインタと低速ポインタを解決します。リングがある場合は全体がつながっていることを意味します。次に、この時点で高速ポインタと低速ポインタを設定します。高速ポインタは一度に 2 ステップ移動し、低速ポインタは 2 ステップずつ移動します。一度に1ステップずつ移動します。このように、リングが存在する場合、高速ポインタと低速ポインタは遅かれ早かれ出会うことになります。これは、リンクされたリストにリングが存在することを意味します。
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
# 判断是否有环,快慢指针。
# 若有环,则快慢指针必然会相遇
slow = fast = head # 快慢指针,开始都在头结点处
while fast:# 当快指针不为空时,开始遍历。
fast = fast.next # 先快指针前进一步
if fast: # 如果此时快指针不为空,继续前进一步。(避免出现示例3的情况,一步一步测试)
fast = fast.next
if fast == slow: # 如果快慢指针相遇,则返回True,说明有环
return True
# fast = fast.next.next
slow = slow.next # 慢指针前进一步
return False
注:指輪がある場合、指輪の長さはどのように判断すればよいですか?
この方法では、速いポインターと遅いポインターが出会った後、2 回目に出会うまで動き続けます。遭遇間の移動数がループの長さになります。