目录
写在前面的话
小伙伴们大家好啊!上篇文章我们对于链表带环问题的两个题目做了分析,并以代码方式实现了,今天我们对于上篇文章提到的,关于为什么使用双指针,以及入口节点规律的问题,给大家做一个同一解答。
一,为什么fast一次走两步,slow一次走一步
好的,那么对于这个问题。我们通过以下步骤来分析。
1.1结论
首先,我们先说结论。
1.如果链表带环,则 fast 一次走两步,slow一次走一步的情况下,两指针一定会相遇。
2.如果链表带环,fast 指针依次走三步,四步……n步,slow一次走一步,不一定能追上。
1.2走两步证明
那么我们来证明一下。
第一步:
那么我们看到,一开始的时候,两个指针都是指向链表头节点的,然后这时候,fast 走两步同时slow走一步,当快指针 fast 一次走两步的时候,fast 指针一定是先入环,此时,slow 才走了入环之前一般的距离。
第二步:
当再走几次之后,当 slow 第一次入环的时候,此时 fast 已经走了一段距离,但是具体有多少,需要根据环的大小来决定。此时我们假设俩个指针之间的距离是 N。
第三步:
接下来两个指针都在环内走,两个指针每走一次,他们之间的距离就缩小 1,变成了 N-1 ,因为快指针一次走两步,而慢指针只能走快指针的一半。那么继续走,一定会有一次,使得距离从 N 减小到 1,因为 N 一定是 1 的倍数。
1.3走三步,甚至多步证明
那么接下来我们对于走三步甚至四步这样的情况也作一解释:
那么经过上面的思路,我们知道了,如果链表带环的情况下,当两个指针一起走时,每次都会减少一定的步数,然后当这个步数减为 0 的时候,两个指针就相遇了。
但是如果快指针走三步的情况下,就会有以下情况:
如上图所示,当 slow 指针进环时,我们发现,假设环大小为 C ,那么如果 C-1 是偶数的话,是可以追上的。那么我们再来看下面一次走四步。
那么我们看到了,如果距离是 -1 或者 -2 ,说明如果 C-1 或者 C-2 是 3 的倍数的话,可以追上。
所以我们发现,走多步是可以的,但是不一定完全可以。因为你必须知道环的长度才能计算,那样做就不符合我们做链表带环题的初衷了。
1.4带环问题实现方法
那么经过上面的分析之后,我们发现,其实我们用最开始的走两步的思路实现,是一定可以的。因为任何正整数都是 1 的倍数。我们也不用去考虑其他步,因为其他步不一定能追上。
所以在以后对于带环题目,相信小伙伴们一定都会机智的去选择快指针走两步的方法。
二,入环第一个节点
2.1入环规律分析
好的,那么经过上面的分析之后,我们可以用双指针实现判断链表是否是带环链表。那么接下来我么分析一下,怎么样去找出入环的第一个节点是什么?
首先我们需要找到规律,那么也就是 fast 一次走一步,而 slow 一次走两步。那么我们就有以下实现:
我们将入环之前的那一段记为 L,然后将两个指针的第一次相遇的地方记为 meet ,然后从入环节点到该相遇点之前的这一段距离记为 X,然后将环的长度记为 C。那么我们就可以得到:
那么我们将该公式化简到最后一步时,我们发现,L 可以表示头指针 head 从头节点走到入环第一个节点的位置时,经过的路程距离。而后面的一整个部分表示 meet 指针从 meet 位置开始,走了N 圈环的长度,再加上从 meet位置 走到入环节点时候的距离。
2.2实现方法总结
所以这里总结求入环第一个节点的方法:
首先,我们需要找出第一次 fast 和 slow 指针相遇的地方,然后将其记为 meet 。之后,我们将链表头指针 head 以及 meet 同时移动,当他们两个第一次相等的时候,就是入环的头节点。这是我们上面得出的公式中的规律。
好的,那么我们对于本文的分享到此就结束啦,如果小伙伴们还有问题或者小编的文章有问题,还请指正呀!