【问题标题】:Generating suffix tree of string S[2..m] from suffix tree of string S[1..m]从字符串 S[1..m] 的后缀树生成字符串 S[2..m] 的后缀树
【发布时间】:2013-04-30 17:32:48
【问题描述】:

是否有一种快速(O(1) 时间复杂度)的方法可以从字符串 S[1..m] 的后缀树生成字符串 S[2..m] 的suffix tree

我熟悉 Ukkonen,所以我知道如何从字符串 S[1..m] 的后缀树制作字符串 S[1..m+1] 的快速后缀树,但我无法应用该算法对于相反的情况。

【问题讨论】:

  • 我猜不是。基本上我们需要做的就是删除S[1..m]的后缀树中的字符串[1..m]。是什么让您认为存在恒定时间复杂度算法?
  • 如果我没记错的话,难点在于识别S[1..m]对应的是哪个叶子节点。一旦你有了叶子,我认为(但没有尝试实际写下证明)删除该叶子和(如有必要)指向它的内部节点应该是 O(1)。找到叶子是 O(m),但您可以使用 O(1) 额外空间来维护指向树中最深叶子的指针,这会将叶子查找时间减少到 O(1)。删除叶子后,您必须更新该指针,但如果树中有后缀链接,则可以在 O(1) 摊销时间内完成。
  • Ukkonen 的算法通过从左到右构建后缀树来实现 O(n) 复杂度。在此之前的算法是从右到左构建它,并且都未能达到 O(n)。所以我猜不是。

标签: algorithm data-structures complexity-theory suffix-tree


【解决方案1】:

好吧,正如@jogojapan 所说,要从 S[1..m] 树中获取 S[2..m] 树,我们需要:

  • 找到位置 0 的叶子 L
  • 如果 L 有多个同级,则删除 L 的父级指向 L 的指针
  • 如果 L 正好有一个兄弟,则将指针从 L 的祖父母更改为 L 的父母,使其指向 L的兄弟姐妹。

@jogojapan 进一步建议您保留指向树中最深叶子的指针。这样做有两个问题:L 不一定是树中最深的叶子,如 Wikipedia's example shows,其次,如果您希望能够输出与收到的相同类型的数据结构,一旦删除 L 你需要找到 new position-0 叶,这将花费 O(m) 时间。

(你可以做的是在 O(m) 时间内构造一个指向每个叶子的指针数组,并在另一个 O(m) 时间内按位置对它们进行计数排序。然后你就可以构造所有的树 { S[t..n] : 1 在恒定的摊销时间内)

假设您对摊销时间不感兴趣,让我们证明您所要求的是不可能的。

  • 我们知道任何修改 S[1..m] 的后缀树的算法都必须从根开始:它不能从其他任何地方开始,因为我们对底层的具体数据结构一无所知,而且我们不知道树的节点有 parent 指针,所以唯一可以访问整个树的位置是根。
  • 我们也知道,它必须先定位到位置为 0 的叶子,然后才能希望将数据结构修改为 S[2..m] 的后缀树。为此,它显然必须遍历根和位置 0 叶之间的每个节点。
  • 问题是,考虑a^m的后缀树(字符a重复m次):路径的长度是m-1。所以任何算法都必须至少访问 m-1 个节点,因此在最坏的情况下需要 O(m) 时间。

【讨论】:

    猜你喜欢
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 2015-10-06
    • 2011-10-26
    相关资源
    最近更新 更多