刷题碎碎念一:环形链表快慢指针之为什么

背景

用快慢指针找环形链表是个非常非常非常常见的题型,之前在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$,这个事情就是很自然而然的了对不对

好了欢乐结束了希望不要再忘了