最近我正在学习如何使用树来解决最常见的子串问题。在从Wiki和其他在线资源中学习之后,我发现我们应该使用后缀树来找到最长的公共子串。
正如维基所说:
可以找到一组字符串中最长的公共子串 为字符串构建一个通用后缀树,然后找到 最深的内部节点,其中包含来自所有字符串的叶节点 在它下面的子树中
正如Justin所说:
String = ABCDE$XABCZ$
End of word character 1 = $
└── (0)
├── (20) $
├── (22) ABC
│ ├── (15) DE$
│ └── (23) Z$
├── (24) BC
│ ├── (16) DE$
│ └── (25) Z$
├── (26) C
│ ├── (17) DE$
│ └── (27) Z$
├── (18) DE$
├── (19) E$
├── (21) XABCZ$
└── (28) Z$
在(紧凑)后缀树中,您需要找到所有字符串中包含叶节点的最深内部节点。 如果在同一深度有多个节点,则必须比较该节点表示的字符串的长度。即ABC,BC和C都具有相同的深度,因此您必须比较ABC,BC和C字符串的长度,以查看哪个更长;这显然是ABC。
在这里,我认为从所有字符串中找到具有叶节点的最深内部节点的过程实际上是从所有字符串中找到所有后缀的最长公共前缀的过程。
所以这是一个问题: 为什么我们不构建存储所有字符串中所有后缀的前缀树?然后我们可以搜索前缀树以找到这些后缀的最长公共前缀。我无法区分这两者之间的区别。任何人都可以给我一些线索,为什么我们使用后缀树而不是前缀树来解决这个问题?
答案 0 :(得分:3)
对于长度为O(N)
的字符串,后缀树仅需要N
时间和空格。这就是为什么使用它可以在线性时间内解决最长的常见子串问题
在最糟糕的情况下,将字符串的所有足够的内容添加到特里结构需要O(N^2)
时间和空间。
因此,您想要将所有字符串的所有内容添加到trie实际上是正确的,但与具有后缀树的解决方案相比效率低。
答案 1 :(得分:0)
trie用于字典。它不存储后缀。