给定一个链表的头节点head
,返回链表开始入环的第一个节点。如果链表无环,则返回null
。
如果链表中有某个节点,可以通过连续跟踪next
指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置**(索引从0
开始)**。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改链表。
提示:
- 链表中节点的数目范围在范围
[0, 10^4]
内 10^5 <= Node.val <= 10^5
pos
的值为-1
或者链表中的一个有效索引
进阶:你是否可以使用O(1)
空间解决此题?
直接进阶吧,搞哈希表太没水准了
这里主要是一个数学问题,我们弄两个快慢指针遍历链表:快指针每次前进两个节点,慢指针每次前进一个节点。
如果链表无环,那么快指针到达空指针处,返回结果。
如果链表有环,那么快慢指针会在环内相遇。设环外节点数为a,环内节点数为b,快慢指针相遇时快指针前进了f个节点,慢指针前进了s个节点。
首先快指针速度是慢指针的两倍:f = 2s
其次快指针比慢指针多走的节点数为环内节点的整数倍:f = s + nb
联立上面两个有:s = nb
也就是此时慢指针走过的节点数为环内节点数的整数倍。也就是再走a个节点能够到达环的起点数。
为了获得a,让快指针打道回府回到起点处,快慢指针同时前进,每次都移动一个节点。当二者相遇时,即是在环的开始处。
说完啦!上代码!
1 | /** |