背景
用快慢指针找环形链表是个非常非常非常常见的题型,之前在leetcode find duplicate number 见到了环形链表的解法,就顺手算了一下,算完给自己留个纪念(毕竟这可能是第三次算这东西了。。。)(每次都像是什么崭新的知识点)
快慢指针找环形链表解法
过分经典在这里放个链接顺便随便说说吧:https://leetcode.cn/problems/c32eOV/solutions/1037744/lian-biao-zhong-huan-de-ru-kou-jie-dian-vvofe/
简单来说就是有一个快指针fast
和一个慢指针slow
,快指针每次往前走两步,慢指针每次往前走一步,如果两个指针最终相遇,那就说明这个链表是个环形链表
那怎么找入环口呢?
在两个节点相遇之后,掏出一个新的指针 ptr
指向链表头部,然后和 slow
每次往前走一步,这两个指针就会在入环点相遇
原理
感觉真的算了很多次了但是每次都记不住QAQ
来随便写个个链表:
HEAD–B–…–C–Enter–D–…–Enter
假设:
- 从head到Enter(不包含)一共
a
步 - 环内一共
b
节点(包含enter) - 环内相遇时包含Enter和相遇节点一共距离enter
x
节点 - $\alpha$ 和 $\beta$ 是模数,任意
那么当fast和slow相遇时,可以写个公式:
$a + x + \alpha b = 2(a+x)$
所以也就可以得知: 只要有一个 $x >= 1 \&\& x <= b$ 时满足:当 $a + x = \alpha b$ 就可以
那就很简单了,$x=b - (a \bmod b)$
再来看一下找入环口这件事情的公式,一共走了a+1步:
$a + 1 + x = \beta b + 1$
看 $a + x = \alpha b$,这个事情就是很自然而然的了对不对
好了欢乐结束了希望不要再忘了