链表06-环形链表
题: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

本道题主要由两个考点组成
- 判断链表中知否含环
- 找到环的入口
一、是否含环的判断
有环的判断非常简单 ,就是看快慢指针最后会不会在环内相遇
我们让fast指针每次走两步 slow每次走一步 ,那么当slow fast都进入环内时,就变成fast追赶slow,并且两者的步伐每次差一步,所以fast最后一定可以撞上slow指针。
但是如果fast每次走三步 就可能出现fast直接超过slow,不相遇的情况
判断有无环的代码如下
1 | class Solution(object): |
二、找到环的起点
判断环的起点后,如何才能找到环的起点呢 ,说实话,不是那么好理解,画图和列公式来辅助

如图,我们把整个链表的路径分成x, y ,z三段,那么我们就可以得到
slow指针的总路径:x + y
fast指针的总路径:x + n(y+z) + y (其中n为快指针绕的圈数,n>=1)
抓住快指针走过的路径是慢指针的两倍:
2(x + y)=x + n(y + z) + y
化简,变化后的结果是
x = (n - 1) (y + z) + z
这个公式说明,此时如果从起点和相遇点同时放一个指针,保持同样的速度一起走,那么他们相遇的时候,相遇点一定就是环的入口。至于n的取值根本无所谓,取多大无非就是环内的指针多转几圈,反正最后的一定要在环口相遇。
实在不好理解就死记吧 相遇点和起点分别放指针,相遇便是环起点
完整题解代码如下
1 | # Definition for singly-linked list. |