链表环路检测及环入口定位是一个非常经典的算法问题,它可在死锁检测等实际应用场景发挥重要作用。想必大家都知道这个问题应该使用快慢指针去求解,因为它具有最优的时间复杂度O(n)。但是大家可能对快慢指针的数学原理不是很清楚,为啥它能达到最优。详细读了这篇文章,大家必定豁然开朗,掌握快慢指针背后的数学原理。
我们直接来看图。
先讲一下链表环路检测的原理,相比环入口定位,原理比较简单。
起点设置两个快慢指针,同时开始往后跑,每跑一次必须检测快指针是否到达链表末尾(下一个节点值为null),如果到达链表末尾则证明该链表无环。如果该链表存在环,则快慢指针总有邂逅(相遇)的那一刻,由此每跑一次,除了检测快指针是否到达链表末尾,还需检测快慢指针所在节点是否相同,相同则代表两指针相遇了,即环存在。为什么环存在时快慢指针一定会相遇呢,想必不用过多解释了,举个简单生活中例子,两个人在足球场跑步,同一起点出发,跑的快的人一定会在某一时刻追上跑的慢的人(多跑一圈)。
现在来分析环入口定位的原理。
环入口定位的前提是先找到快慢指针相遇点,即上述所讲的链表环检测操作(注意存在一个限定条件,快指针的步长必须为2,慢指针步长必须为1)。当找到相遇点后,在起点处和相遇点处分别设置指针p1和p2,步长均为1,它们同时往后跑,当p1,p2相遇时,它们的相遇点便是环入口。
现在来一波数学推理,证明一下上述算法的正确性。