我读过:
在txt [1..n]中搜索子字符串pat [1..m],可以在O(m)时间内解决(在Oxt中构建txt的后缀树之后) n)时间)。
但是在每个点上,我们必须选择要采用的分支,因此就像在n-ary树中一样,在每个节点处,我们必须与该节点中的所有最大n个指针进行比较,以决定采用哪个分支。这不会给这个算法的复杂性带来因素,不知何故在图片中
然后如何说它可以在O(m)中找到子串?
我在这里缺少什么?
答案 0 :(得分:5)
然后如何说它可以在O(m)中找到子串?
遗漏。你是正确的,在后缀树中搜索的运行时间比仅仅O(m)更复杂。
然而,如果我们权衡空间要求,它确实可以加速到O(m):我们需要将每个节点的搜索降低到O(1),我们可以做到这一点通过使用适当的数据结构(例如数组),它为我们在恒定时间内为每个字母提供适当的子树。
例如,假设您使用C ++进行实现,而您的角色(char
)可以包含256个不同的值。然后,节点的实现可能如下所示:
struct node {
char current_character;
node* children[256];
};
现在,current_character
指的是指向当前节点的分支的字符,children
是一个子节点数组。在搜索过程中,假设您当前位于节点u
,输入文本中的下一个字符为c
。然后,您将选择下一个节点,如下所示:
node* next = u->children[c];
if (next == 0) {
// Child node does not exist => nothing found.
}
else {
u = next;
// Continue search with next …
}
当然,这仅适用于非常小字母(例如基因组序列的DNA)。在大多数常见情况下,后缀树的最坏情况运行时确实高于O(m)。
答案 1 :(得分:0)
如果指向子节点的指针在字母索引的数组中,则每个模式字母只需要不变的时间
node = tree root
FOR i in 1..m
node = child[pat[i]]
因此复杂度为O(m)。