题目:
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
答案:
快慢指针,设置fast和slow,两者都从head出发,有两种结果:
1、两者没有相遇,fast或者fast.next不存在,说明无环
2、两者相遇了,当两者第一次相遇时,fast和slow走的步数满足下面条件:
fast = 2 slow
fast = slow + nb
(此处设直线区域的节点数为a,环形区域的节点数为b)
两式计算可得:fast = 2nb slow = nb
也就是说slow走了nb步。
如果我们从head开始计算步数,走到环形入口处需要走a + nb 步,此时slow已经走了nb步了,那么它再走a步就一定停在了环形入口处,但是这个a怎么算呢?
我们只需要在此时将fast置于head处,与slow同速走,两者相遇时,就找到了我们要找的节点。
返回fast即可。
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow, fast = head, head
while True:
if not fast and not fast.next:
return False
fast, slow = fast.next.next, slow.next
if fast == slow:
break
fast = head
while fast != slow:
fast, slow = fast.next,slow.next
return fast