在恒定时间和线性空间中找到两个字符串的 LCP

Posted

技术标签:

【中文标题】在恒定时间和线性空间中找到两个字符串的 LCP【英文标题】:finding LCP of two strings in constant time and linear space 【发布时间】:2020-01-03 16:28:59 【问题描述】:

这就是问题所在: 假设 S 是一组字符串,我们知道 nS 中所有字符串的总长度。我们必须找到一个空间为 O(n) 的数据结构,它在 O(1) 中找到 LCP(s,t),其中 LCP 是字符串之间最长的公共前缀 s,t.

起初我以为我可以使用散列,因为我们可以在恒定时间内检查数字并在恒定时间内找到子字符串,如果我们预先散列字符串。但我认为这不会起作用,因为它需要更多空间和经过一番搜索,我发现解决方案可能在于使用 Trie's、Suffix 数组以及 LCA 和 RMQ。我想我已经接近答案了,但不知道这些概念如何协同工作来构建一个能够快速提供 LCP 的数据结构!

感谢阅读

【问题讨论】:

能否假设每个字符串的长度为sqrt(n),并且有sqrt(n)字符串? @Yonlif 我不这么认为。我们只知道它们的总长度是n 我在考虑使用比 sqrt(n) 更长的字符串进行重度轻分解。 @Yonlif 喜欢压缩树吗? 什么是s和t?因为如果它们是字符串,那么您甚至无法在恒定时间内识别它们。如果它们是可以在恒定时间内映射到内部节点的东西,那么您可以对 trie 进行 LCA 查询。 【参考方案1】:

我想我知道他们正在寻找的答案。

首先,为所有字符串构造一个 trie。 trie 中的每个节点都可以包含一个指向以该前缀开头的字符串的指针和一个长度。将每个字符串映射到该字符串结束的 trie 中的最后一个节点。

现在,当给定一对字符串(大概你被告知为字符串i 和字符串j)时,返回字符串的问题是找到最不共同的祖先,然后返回一对(pointer_to_start_of_string, length) .

但是一个 trie 可以写成一棵树,然后 Tarjan 的离线最低 Common Ancestors Algorithm(参见 https://www.geeksforgeeks.org/tarjans-off-line-lowest-common-ancestors-algorithm/)可用于预处理该树以非常快速地回答 LCA 问题。

技术上它不是O(1)。然而,它是O(inverse_ackermann(n)),对于任何适合可观测宇宙的计算机来说,它都可以被视为一个相当小的常数。

【讨论】:

Trajan 的 LCA 是一种离线算法,即使经过预处理,也无法在这段时间内回答任意单个查询。有一种方法可以在使用线性空间进行预处理后在恒定时间内完成,方法是使用树的欧拉之旅将问题减少为范围最小查询。见geeksforgeeks.org/find-lca-in-binary-tree-using-rmq 和en.wikipedia.org/wiki/Range_minimum_query

以上是关于在恒定时间和线性空间中找到两个字符串的 LCP的主要内容,如果未能解决你的问题,请参考以下文章

扩展KMP(Z函数),线性LCP

两个非线性三维方程的数值解

线性表

向量空间中的:线性相关与线性无关

向量空间中的:线性相关与线性无关

线性代数和numpy