KMP算法-时间复杂度

时间:2019-07-15 17:14:34

标签: algorithm

发现kmp算法的预处理部分的时间复杂度

我正在研究KMP。但是我无法理解该算法的时间复杂度。有人可以解释吗?

2 个答案:

答案 0 :(得分:0)

我们正在尝试计算通常称为PI的函数值。

首先让我们定义我们的PI函数。令S为我们的字符串。 PI(i)= x <=> x是S子串的最长后缀的长度,从S的第一个字符开始,到S的第i个字符(也是S的前缀)结束。

示例:

S:AAABACD

PI:0120100

让S(i)为长度为i的S的前缀。

假设我们已经拥有所有值PI(1),PI(2),...,PI(i-1)。计算PI(i)的时间复杂度为O(n)。 我们尝试扩展S(i-1)的最长前缀和后缀。 如果可能的话,我们就做,所以PI(i)= PI(i-1)+ 1。 如果不是,我们尝试使用最长前缀和后缀中的最长前缀和后缀(但是听起来可能很奇怪),依此类推。显然,我们尝试扩展的新子字符串的长度至少比上一个小1。 当我们到达长度为0的子字符串时,PI(i)= 0。 这就是为什么此步骤的复杂度为O(n)的原因。

因为我们计算所有1 <= i <= n的PI(i),所以复杂度是O(n ^ 2)...还是它?

让我们谈谈摊销的复杂性。 由于每次我们尝试另一个前缀和后缀时,我们都会将检查的子字符串的长度减少至少1,因此,在不超过PI(i-1)-1个步骤之后,我们肯定会停止算法。 令x为我们为所有1 <= j <= i-1尝试另一个前缀和后缀的次数。然后PI(i-1)<= i-2-x。 (如果x = 0,则对于所有1 <= j <= i-1,PI(j)= PI(j-1)+1。在进行了x次附加试验后,我们减小了PI(j)的值。对于j至少x。) 我们可以看到x

答案 1 :(得分:0)

KMP的时间复杂度为O(n)。 KMP有一个内循环和一个外循环。最长的匹配前缀变量i初始化为0,并且在外循环中最多以n为文本字符串的长度以1的步长递增。 内部循环迭代地减少i,但它在0处停止。 因此,只有当外部循环先前将其递增时,内部循环才可以减少i,最多可以发生n次。

您可以将i的值视为一种资源,该资源由外循环以1的步长产生,并由内循环以⩾1的步长消耗,直到耗尽为止。