簡體   English   中英

是否可以在 O(n) 中計算字符串中不同子串的數量?

[英]Is it possible to count the number of distinct substrings in a string in O(n)?

給定一個長度為n的字符串s ,是否可以在 O(n) 中計算出s中不同子串的數量?

例子

輸入: abb

輸出: 5 ( 'abb', 'ab', 'bb', 'a', 'b' )

我做了一些研究,但我似乎找不到以如此有效的方式解決這個問題的算法。 我知道 O(n^2) 方法是可能的,但是有更有效的算法嗎?

我不需要獲取每個子字符串,只需要獲取不同子字符串的總數(以防有所不同)。

您可以使用 Ukkonen 算法在線性時間內構建后綴樹:

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

s 的子字符串數就是 trie 中字符串的前綴數,您可以在線性時間內簡單地計算出來。 它只是所有節點中的字符總數。

例如,您的示例生成如下后綴樹:

            /\                
           b  a
           |  b
           b  b

樹中有 5 個字符,所以有 5 個子字符串。 每個唯一的字符串都是從根開始的路徑,以不同的字母結尾:abb、ab、a、bb、b。 所以字符串的數量就是樹中字母的數量。

更確切地說:

  • 每個子串都是字符串的某個后綴的前綴;
  • 所有的后綴都在trie中;
  • 所以通過trie的子串和路徑是一一對應的(根據trie的定義);
  • 樹中的字母與非空路徑是一一對應的,因為:
    • 每個不同的非空路徑在其最后一個字母之后的不同位置結束;
    • 每個字母后面的位置的路徑是唯一的

對於想知道如何在 O(N) 時間內構建包含 O(N^2) 個字符的樹的人們請注意:

后綴樹的表示有一個技巧。 不是將實際字符串存儲在樹的節點中,而是將指針存儲到原始字符串中,因此包含“abb”的節點沒有“abb”,它有 (0,3) -- 每個 2 個整數節點,不管每個節點中的字符串有多長,后綴樹有O(N)個節點。

構造LCP 數組並從子串數 (n(n+1)/2) 中減去它的總和。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM