数据结构

判断单链表是否有环、求环长和环入口最优算法

2019-11-05  本文已影响0人  程序员will

判断单链表是否有环、求环长和环入口最优算法

判断单链表是否有环是一个十分经典的算法问题,许多考试或者面试都有很大的几率出现。如果事先对此没有一定的理解,临场发挥可能就比较困难了。

判断链表是否有环

判断单链表是否有环、求环长和环入口最优算法

判断单链表是否有环、求环长和环入口最优算法

为什么 slow==fast 就一定会存在环呢?

因为,如果存在环,fast 和 slow 肯定会先后进入环;

当 slow 刚好进入环时,fast 肯定已经在环内的某一个位置了;

而又因 fast 走的速度是 slow 的两倍,所以在 slow 在环内遍历一遍的过程中,fast 指针必然会与 slow 相遇。

其实两个指针就像是两个人在田径场上跑步,一个人的速度是另一个人速度的两倍。无论两个人的起点在何处,慢的人跑完一圈,快的人必然跑完两圈,所以他们必然相遇过。

复杂度分析

设链表长度为 n,显然时间复杂度为 O(n);

空复杂度为 O(1)。

求环的长度

上面已经可以判断出是否有环了,如果有环,那么环的长度又是多少呢?该怎么求?

这就很简单了,前面已经将环判断出来了,所找到的 slow 和 fast 相遇点必然是在环内的,记录该节点;

所以此时只需用一个指针 p 继续一步步遍历链表,并计数,直到指针 p 重新指向上面的相遇节点,此时计数的值就为环长了。

复杂度分析

设链表长度为 n,环长为 r 。

如果是在知道一个环内节点的情况下,那么时间复杂度为 O(r),空间复杂度为 O(1);

如果是在不知道是否有环的情况下,那么时间复杂度为 O(n+r),空间复杂度为 O(1)。

求环的入口

前面已经判断出是否有环了,并求出了环的长度,此时求环的入口也变得很简单了。

这个应该很容易理解吧,q 比 p 先走了一个环的长度,所以当 p 刚好走到环的入口时,q 就刚刚好遍历了环一遍。

复杂度分析

设链表长度为 n,环长为 r 。

如果是在知道一个环长度的情况下,那么时间复杂度为 O(n),空间复杂度为 O(1);

如果是在不知道环长度的情况下,那么时间复杂度为 O(n+r+n)= O(n+r),空间复杂度为 O(1)。

求链表的长度

链表长度 = 头结点到环入口节点的长度 + 环长度

所以此时,只需用一个指针从头遍历链表节点并计数,求出头结点到环入口节点的长度即可。

上一篇下一篇

猜你喜欢

热点阅读