📜  在链表中查找循环的第一个节点(1)

📅  最后修改于: 2023-12-03 15:37:47.337000             🧑  作者: Mango

在链表中查找循环的第一个节点

链表是一种常用的数据结构,它可以用来存储一个序列的元素,并且支持插入和删除操作。链表可以分为单链表和双向链表,以及循环链表和非循环链表。在循环链表中,最后一个节点的下一个节点指向第一个节点,形成一个环。

在循环链表中查找循环的第一个节点是一个常见的问题,下面我们来介绍一下实现的方法。

方法一:使用哈希表

我们可以使用哈希表来存储每个节点的地址,然后遍历链表,对于每个节点,先查询哈希表中是否已经存在该节点的地址,如果不存在,则将该节点的地址添加到哈希表中;如果存在,则该节点就是循环的第一个节点。

时间复杂度:O(n) 空间复杂度:O(n)

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        seen = set()
        node = head

        while node:
            if node in seen:
                return node
            seen.add(node)
            node = node.next

        return None
方法二:使用快慢指针

我们可以使用快慢指针来判断链表是否存在环,并找到循环的第一个节点。首先,使用快慢指针找到相遇点,当快指针和慢指针在相遇点相遇时,将慢指针移动到链表头,然后快指针和慢指针以相同的速度往前移动,当它们再次相遇时,就是循环的第一个节点。

时间复杂度:O(n) 空间复杂度:O(1)

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow = fast = head

        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

            if slow == fast:
                slow = head

                while slow != fast:
                    slow = slow.next
                    fast = fast.next

                return slow

        return None

注意事项:

  • 链表可能为空或只有一个节点,此时不存在循环,应该返回 None。
  • 代码中的 ListNode 是链表节点的类,节点包括两个成员变量:val 表示节点的值,next 表示下一个节点的指针。
  • 代码中的 head 是链表的头节点,tail 是链表的尾节点,如果链表是循环的,则 tail 的 next 指针指向 head。