题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
牛客网:链表中环的入口节点
解题思路
(1)首先需要确定链表中是否包含环,可以用两个快慢指针 fast 和 slow 表示:两个指针同时从链表的头结点出发,fast 一次走两步,slow 一次走一步。如果走得快的指针追上; 走的慢的指针,那么链表就含环(当一个链表含环时,指针已进入该环的节点就一直绕圈圈);如果走的快的指针走到了链表的末尾(fast.next 指向 null)都没有追上走的慢的指针,那么链表就不含环。
(2)接下来找环的入口,我们可以用两个走的一样快的指针 first 和 last 解决。方法是先让他们都指向链表的头节点。如果链表中的环有 n 个节点,则指针 first 先在链表上向前移动 n 步,然后两个指针以同样的速度向前移动。当 last 指针指向环的入口节点时,first 指针已经围绕着环走了一圈,回到了入口节点,此时,两个节点在入口节点相遇。
分析:
当 first 绕环一周时(first 进入环之前已经走过前几个非环的节点),就代表 first 走了 n 步,即走遍了整个链表。
如果此时没有环的话,说明 first 已经走到链表的末尾,但是现在有环,说明链表的最后一个节点并不是指向 null,而是指向了环的入口节点。
整个过程 first 比 last 多走了 一个环的长度 nodesInLoop ,即 last 走了 链表总长度 - 环的长度 = n - nodesInLoop; 此时 last 刚好走到入口节点,说明两者相遇的节点就是我们要找的环的入口节点