题目描述
给定一个链表的头节点 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")
自己看到题目的第一想法
初始的思路是通过遍历链表中的每个节点,将它们逐一存储到一个数组中,然后通过比较数组中的节点找到相交的节点,最终返回这个节点。
看完代码随想录之后的想法
- 在解决这个问题之前,先进行判断链表是否存在环,使用快慢指针判断指针是否相遇。
- 若存在环,进一步寻找环的入口节点。从链表头节点和相遇节点分别出发两个指针,每次只移动一个节点。当这两个指针再次相遇时,即可确定环形链表的入口节点。