LeetCode (力锋) 142 questions: circular linked list II - fast and slow pointer solution with detailed notes

题目描述

Given a linked list, return the first node where the linked list starts to enter a loop, or None if the linked list has no loops.
To represent a cycle in a given list, we use Pos to denote the position in the list where the tail of the list is connected (indexed from 0). If Pos = -1, there are no cycles in this linked list. Note that Pos is only applicable to the identification ring and will not be passed as a parameter to the function.
Description : Modification of the given linked list is not allowed

示例

insert image description here

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

insert image description here

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

insert image description here

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

思路分析

The title asks us to find the node where the linked list enters the ring. I believe that everyone has run around in the school playground. Compare the ring part of the linked list to the playground, and the entrance of the playground to the node where the linked list enters the ring . Suppose you and a pair of small Couples start from the school gate to run on the playground at the same time. You are running (you have been running), and you are like a fast pointer . The two of you are like slow pointers, and there will always be a moment when you meet at the place where the young couple stops to rest. If the place where the couple sits down to rest and fall in love happens to be at the gate of the playground, and you happen to run to the gate of the playground, then congratulations on meeting you! You met at the gate of the playground! ! You met at the position where the linked list enters the ring! ! ! Hurry back to where you are right now.

In the code design, a pair of fast and slow pointers is set. Initially, the fast and slow pointers are located at the head node. At the same time, a collection is defined to record the path passed by the fast pointer to determine whether the fast pointer has circled the ring part. The slow pointer moves forward each time. A node, and then the fast pointer moves forward around the ring part. If the fast and slow pointers do not meet after the ring circle, it means that the current position of the slow pointer is not at the node entering the ring. Then the slow pointer moves forward by one node, and the fast pointer continues to move forward One week, continue to judge until the fast and slow pointers meet, then the position where they meet is the position where the linked list enters the ring. The logic is like this, let's take a look at the details of the code design.

代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        # 当链表中头节点为空或者只有头节点的时候,不满足环形链表形成的条件,返回None
        if head is None:
            return None
        elif head.next is None:
            return None
        # 定义快慢指针,初始位置都指向头节点
        seen = set()
        slow, fast = head, head
        # 以慢指针走到链表终点为循环终止条件
        while slow:
        	# 快指针在当前慢指针位置的前提下绕链表环形一周,如果与慢指针相遇,则返回
        	# 如果没有相遇,那么终止循环,慢指针前行一个节点,继续进入循环判断
            while fast not in seen and fast is not None:
                seen.add(fast)
                fast = fast.next
                if slow == fast:
                    return fast
            seen.clear()
            slow = slow.next        
        return None      

运行结果

insert image description here

Guess you like

Origin blog.csdn.net/Just_do_myself/article/details/118484714