题目
如果一个链表中包含环,如何找出环的入口节点?
思路
- 确定是否包含环;
- 找到环中节点的数目;
- 找到环的入口。
1. 确定是否包含环
快慢指针。快指针一次走两步,慢指针一次走一步。
如果快指针追上慢指针,则有环;
如果快指针走到链表末尾(指向None)没有追到慢指针,则没有环。
2.找打环中节点的数目
快指针追上慢指针,相遇的节点在环中。
从这个节点出发,边移动边计数,再次回到这个节点,就得到环中节点数。
3. 找到环入口
快慢指针。参考倒数第k个节点。假设环中有n个节点,快指针先移动n步,慢指针再开始。随后同样速度移动,当慢指针指向倒数第n个节点,快指针刚好环入口。
https://leetcode-cn.com/problems/linked-list-cycle-ii/
代码
# Definition for singly-linked list.# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution:def detectCycle(self, head: ListNode) -> ListNode:# 首先初始化快指针和慢指针,确保快指针走的路的长度是慢指针长度的2倍if head and head.next:fast = head.next.nextslow = head.nextelse:return None # 说明无环# 进行循环,首先让快指针和慢指针第一次相遇while fast:if fast != slow:# 快指针走两步if fast.next:fast = fast.next.nextelse:return None # 说明无环# 慢指针走一步slow = slow.nextelse:detection = headwhile detection != slow: # 此时由于slow和fast是一样的,用哪个都行slow = slow.nextdetection = detection.nextreturn detection
