代码随想录算法训练营第四天(4)|142.环形链表II

99 阅读2分钟

题目描述

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

代码示例

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

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 初始化慢指针和快指针,都指向链表头部
        slow = fast = head

        # 判断是否存在环
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                # 当快指针与慢指针相遇时,将新的指针从链表头开始
                new_head_cur = head

                # 两指针相遇即为环的起始节点
                while slow != new_head_cur:
                    slow = slow.next
                    new_head_cur = new_head_cur.next

                return slow

        # 无环的情况
        return None

# 创建链表节点
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)

# 构建环形链表
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node2  # 这里构建一个环

# 实例化 Solution 类
solution = Solution()

# 检测是否存在环,并获取环的起始节点
result = solution.detectCycle(node1)

# 输出结果
print(result.val if result else "None")

自己看到题目的第一想法

初始的思路是通过遍历链表中的每个节点,将它们逐一存储到一个数组中,然后通过比较数组中的节点找到相交的节点,最终返回这个节点。

看完代码随想录之后的想法 

  1. 在解决这个问题之前,先进行判断链表是否存在环,使用快慢指针判断指针是否相遇。
  2. 若存在环,进一步寻找环的入口节点。从链表头节点和相遇节点分别出发两个指针,每次只移动一个节点。当这两个指针再次相遇时,即可确定环形链表的入口节点。