具有至少k次出现正确性的最长重复子串

时间:2016-11-15 14:58:01

标签: string algorithm suffix-tree suffix-array longest-substring

用于查找最长重复子字符串的算法公式如下 1)build the suffix tree 2)find the deepest internal node with at least k leaf children 但我无法理解为什么这样可行,所以基本上是什么使这个算法正确?另外,我发现这个算法的源代码是找到的在O(n)中重复的子串,其中n是子串的长度,这对我来说也不清楚!让我们考虑下面的树,这里最长的重复子串是“ru”,如果我们应用DFS它会找到它5步但不是2步 你能解释一下这些东西吗? 感谢

image

2 个答案:

答案 0 :(得分:0)

我想你完全知道O(n)(Big O表示法)指的是 n 的某个数量的增长顺序,而不是 n 数量等于 n 我写这个是因为读了我怀疑的问题...... 我把它写成一个aswer而不是评论,因为评论有点太长了(我想......)

答案 1 :(得分:0)

给定 N 字符的字符串 S ,构建相应的后缀树是 O(N)(使用诸如{{的算法3}})。

现在,这样的后缀树可以有Ukkonen's(包括root和leaves)。

如果您遍历树并计算从给定节点可到达的叶子数量及其深度,您将找到所需的结果。为此,您从根开始并探索每个孩子。

一些伪代码:

traverse(node, depth):
    nb_leaves <-- 0
    if empty(children(node)):
        nb_leaves <-- 1
    else:
        for child in children(node):
            nb_leaves <-- nb_leaves + traverse(child, depth+1)
    node.setdepth(depth)
    node.setoccurrences(nb_leaves)
    return nb_leaves

初始通话为traverse(root, 0)。由于结构是树,因此每个节点只能调用traverse。这意味着对traverse的最大呼叫数为 2N - 1 ,因此整体遍历仅为 O(N)。现在,您只需跟踪具有最大深度的节点,并通过添加相关的簿记机制来验证:depth > 0 && nb_leaves >= k。这并不妨碍整体复杂性。

最后,找到这样一个子串的算法的复杂性是 O(N)其中 N 是输入字符串的长度(而不是长度)匹配的子串!)。

注意:上面描述的遍历基本上是后缀树上的DFS。