Можно ли подсчитать количество различных подстрок в строке в O (n)?

Дана строка s длиной n, можно ли подсчитать количество различных подстрок в s в O (n)?

пример

вход: abb

выход: 5 ('abb', 'ab', 'bb', 'a', 'b')

Я провел некоторые исследования, но я не могу найти алгоритм, который решает эту проблему таким эффективным способом. Я знаю, что возможен подход O(n^2), но есть ли более эффективный алгоритм?

мне не нужно получите каждую из подстрок, только общее количество различных (в случае, если это имеет значение).

2 ответов


вы можете использовать алгоритм Укконена для построения дерева суффиксов в линейном времени:

https://en.wikipedia.org/wiki/Ukkonen%27s_algorithm

число подстрок s-это число префиксов строк в трие, которое вы можете вычислить просто в линейное время. Это просто общее количество символов во всех узлах.

например, в вашем примере создается дерево суффиксов, например:

            /\                
           b  a
           |  b
           b  b

5 символов в дереве, поэтому 5 подстроки. Каждая уникальная строка-это путь от корня, заканчивающийся после другой буквы: abb, ab, a, bb, b. Таким образом, количество строк-это количество букв в дереве.

более точно:

  • каждая подстрока является префиксом некоторого суффикса строки;
  • все суффиксы находятся в трие;
  • таким образом, существует 1-1 соответствие между подстроками и путями через trie (по определению trie); и
  • существует 1-1 соответствие между буквами в дереве и непустые пути, потому что:
    • каждый отдельный непустой путь заканчивается в определенном месте после его последней буквы; и
    • путь к позиции после каждой буквы уникален

примечание для людей, которые задаются вопросом, как можно построить дерево, содержащее O (N^2) символов в O (N) времени:

есть трюк, чтобы представление дерева суффиксов. Вместо хранения фактических строк в узлах дерева вы просто храните указатели в исходной строке, поэтому узел, содержащий "abb", не имеет" abb", он имеет (0,3) -- 2 целых числа на узел, независимо от длины строки в каждом узле, а дерево суффиксов имеет O(N) узлов.


построить массив LCP и вычесть его сумму из числа подстрок (n (n+1)/2).