我可以检查子序列是否比O(n * n)更快

时间:2014-03-25 14:31:54

标签: c# .net performance algorithm complexity-theory

所以我的问题是主题的名称。是否存在一种算法,该算法检查B是否是A的子序列,比O(N ^ 2)更快,例如O(NlogN)或简单地O(N)?

找到的唯一方法就是简单的强力

for(int i = 0; i < a.Length - b.Length; i++)
{
   if (IsSubsequence(a,b,i))
      return i;
}
return -1;

3 个答案:

答案 0 :(得分:7)

这是David Eisenstat算法的递归表征。 (请注意,此算法是尾递归,因此可以写为循环;我将其描述为递归,因为这样做是理解算法的好方法。)

将序列定义为空,或将项目后跟序列。

取两个序列,A和B.问题是B是否是A的子序列。

如果B为空,则B是A的子序列。

如果B不为空且A为空,则B不是A的子序列。

如果我们做到这一点,A和B都不是空的。假设A是项目X,后面是序列C,B是项目Y,后面是序列D.

如果X与Y相同,那么问题&#34;的答案是B的后续A?&#34;与小问题的答案相同&#34; D是C的后续序列?#34;。回答这个问题。

如果X与Y不同,那么答案问题&#34; B是A的后续序列?&#34;与较小问题的答案相同&#34; B是C的后续序列?#34;。回答这个问题。

此程序终止,显然最坏的情况是序列A的长度。

答案 1 :(得分:3)

是的,使用Knuth, Morris and Pratt算法可以比O(n^2)更快地完成。但请注意,framework提供的实现可能已经实现了此算法。

答案 2 :(得分:2)

是的,以下贪婪算法是正确的,并且在时间O(n)中运行。对于B中的每个元素,按顺序在A中从前一个停止点(最初是A的开头)向前扫描第一次出现。