LeetCode 142. 环形链表 II 题解,寻找链表环入口。
题目
https://leetcode.cn/problems/linked-list-cycle-ii/ 寻找环入口。
题解
数学版本。经过作为运营的女朋友的指导,我懂了数学推导的解法。
假设
假设我们的链表长这样:
B <- <- <- <- <-|
| |
| |
O -> x -> x -> x -> x -> A -> x -> x - > x - > x
其中
- O:链表起点
- x:普通的中间节点
- A:链表环入口
- B:快慢指针相遇节点
- D:distance 表示路程
- s:slow 慢指针路程
- f:fast 快指针路程
- n:相遇时快指针在环内已运行的圈数
- a:OA
- b:环一圈
我们启动两个指针
- 慢指针:slow一次前行一步 slow=slow.next
- 快指针:fast一次前行两步步 fast=fast.next.next
推导
假设现在快慢指针在B点相遇,我们可以得出:
- 快指针路程为慢指针二倍:f=2s
- 快指针路程为慢指针路程(a+AB)加上n圈环路程:f=s+nb
- 综上1-2,可得 s=nb,也就是相遇时,慢指针恰好走了 n圈的环 对应路程
分析:
而我们分析下,当从链表起点走到环入口的地方时,路程满足:a+nb,n==0时则是慢指针刚好第一次经过环入口,之后便是在环内重复绕圈。
此时,根据上方3结论:慢指针恰好走了 nb,那么只要慢指针再走 a 的路程,就到了A点。
因此,程序可以这么写:快慢指针运行,第一次相遇(B点)后,令快指针回到O点,以一步的步长前进,当两个指针再次相遇时,此时恰好是A点,即题目所求。
对应代码: https://github.com/redolog/algorithm-java/commit/60f69f4fa0825e91e9595bf6c549999b3b70ac7f
|
|