给定长度为.
的字符串s
,是否可以计算O(n)中n
中不同子串的数量?
示例
输入:s
输出:abb
(5
)
我做了一些研究,但我似乎无法找到一种能够以如此有效的方式解决这个问题的算法。我知道O(n ^ 2)方法是可行的,但是有更高效的算法吗?
我不需要获得每个子串,只需要获得不同的子串(如果它有所不同)。
答案 0 :(得分:10)
您可以使用Ukkonen算法在线性时间内构建后缀树:
https://en.wikipedia.org/wiki/Ukkonen%27s_algorithm
s的子串数是trie中字符串的前缀数,您只需在线性时间内计算。它只是所有节点中的总字符数。
例如,您的示例生成一个后缀树,如:
/\
b a
| b
b b
树中有5个字符,所以有5个子串。每个唯一字符串是从根后以不同字母结尾的路径:abb,ab,a,bb,b。所以字符串的数量是树中字母的数量。
更确切地说:
注意那些想知道如何在O(N)时间内构建包含O(N ^ 2)个字符的树的人:
表示后缀树的技巧。您只需将指针存储到orignal字符串中,而不是将实际字符串存储在树的节点中,因此包含" abb"没有" abb",每个节点有(0,3) - 2个整数,无论每个节点中的字符串有多长,后缀树有O(N)个节点
答案 1 :(得分:2)
构造LCP array并从子串数(n(n + 1)/ 2)中减去其总和。