LeetCode 环形链表 II 的数学推导

代码可以参考

https://leetcode.cn/problems/linked-list-cycle-ii/solution/142-huan-xing-lian-biao-ii-jian-hua-gong-shi-jia-2/

网上找了很多答案,感觉他们理解还是差了一点

本文讲的是快慢指针那种解法

数学解法一

(快指针一定会比慢指针先进入环里,如果快慢指针相遇,那么快指针一定至少比慢指针领先一圈,也就是下面 k>1)

(假设现在快慢指针相遇,现在都在相遇点)

慢指针走过的路: a + j(b+c) + b

a、b、c就是图中的a、b、c,(b+c)为一圈的路程,j为常数,表示走了j圈 (j>=0)

快指针走过的路: a + k(b+c) + b

a、b、c就是图中的a、b、c,(b+c)为一圈的路程,k为常数,表示走了k圈 (k>=1)

因为快指针走过的路程是慢指针的两倍,由此我们得到下面等式:

快指针路程=2*慢指针路程

a + k(b+c) + b = 2* (a + j(b+c) + b)

开始化简

a + k(b+c) + b = 2* (a + j(b+c) + b)
a + k(b+c) + b = 2a + 2j(b+c) + 2b
k(b+c) = a + 2j(b+c) + b
(k-2j)(b+c) = a + b
(k-2j)(b+c) - b = a
(k-2j-1)(b+c) + (b + c) -b = a  //借(k-2j)(b+c)一个b+c出来
(k-2j-1)(b+c) + c = a

由此得到

a = (k-2j-1)(b+c) + c

解释,即我走一次a的路程,等于我走了n圈b+c的路程再走一次c的路程(n为b+c前面的常数)

回到上图,假设现在快慢指针都在相遇点,这个时候,我使用一个慢指针1从相遇点开始走,另外一个慢指针2从最左边的起点开始走,假设现在都走了 c 的路程,慢指针1则回到环的起点,接下来慢指针1只需要走 (k-2j-1)(b+c) 的路程也就是 (k-2j-1)圈,就能走完a的路程,此时慢指针2也走完了a的路程,则他们在环的起点相遇

所以,从相遇点使用两个慢指针,一个从相遇点走,一个从最左边的起点走,是能在环的起点相遇的

数学解法二

假设起点到入口节点的距离为 a,环的节点数是n,在上图中a为 2,n为4

a+n的大小等于所有的节点数量

如果我们(从最左侧起点)走 a+n个箭头,或者说a+n个next,那么一定会回到环的入口节点

求n很简单,用快慢指针找到相遇点,然后相遇点一定在环里,我们只需要从相遇点一直next到再次遇到相遇点,并统计遇到的节点数量,即为n

上图假设(由快慢指针)得到相遇点为 5,只需要走 2(即a的大小)个next,就能到达环的起点,a不需要知道大小,我们只需要一个慢指针1,从左边起点出发,另外一个慢指针2从相遇点出发,他们同时走a步必相遇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值