Floyd循环检测的运行时复杂性

use*_*951 4 algorithm time-complexity

根据一些在线资源,我提到弗洛伊德循环检测算法的运行时复杂度为O(n)。说,

p = slow pointer
q = fast pointer
m = the distance from start of linked list to first loop node
k = the distance of the meeting point of fast and slow nodes from the first loop node 
l = length of loop
rp = number of loop rotations by p before meeting q.
rq = number of loop rotations by q before meeting p.
Run Code Online (Sandbox Code Playgroud)

运行时间复杂度应为= m + rp * l + k此值如何为O(n)?

Mat*_*ans 8

如果列表具有N个节点,则在<= N个步骤中,快速指针将找到列表的末尾,或者存在一个循环,而慢速指针将在循环中。

可以说循环的长度为M <= N:一旦慢速指针进入循环,快慢指针将永远停留在循环中。每一步,快慢指针之间的距离将增加1。当距离可被M整除时,快慢指针将在同一节点上并且算法终止。的距离将达到由数整除中号<= M步骤。

因此,将慢速指针指向循环,然后使快速指针和慢速指针满足,需要<= N + M <= 2N步,即O(N)

实际上,如果您注意到存在循环,则慢速指针将以N-M步长到达它,因此总步数为<= N,这可以使步数的范围更紧密。

  • “每一步,快慢指针之间的距离将增加1。” 这就是我一直在寻找的直觉,谢谢! (2认同)

use*_*ica 5

如果存在n节点,则保证n在慢速指针遇到慢速指针或找到列表的终点之前,慢速指针的移动不超过步骤。这意味着您要进行O(n)工作以使慢速指针前进,并且快进指针快两倍于O(n)。因此,整个算法为O(n)。

  • 如果存在一个周期,则一旦两个指针都进入该周期,快速指针就会在每次迭代中“跳起来”一步。它需要“追赶”的距离最多是周期的长度,因此慢速指针无法在快速指针追赶之前围绕周期开始第二圈。 (2认同)