Trie、複雑さO(N)に関して次の考えがあります。空のTrieから始めます。単語を1つずつ取り、Trieに単語を追加します。Trieに単語(単語Wiと呼びましょう)を追加した後、考慮すべき2つのケースがあります。
- Wiは、前に追加したいくつかの単語の接頭辞です。Wiという単語を追加しているときに、Trieにノードを追加しなかった場合、このステートメントは当てはまります。その場合、Wiはプレフィックスであり、ソリューションの一部です。
- 前に追加された単語のいくつかはWiの接頭辞です。そのステートメントは、前に追加された単語の終わりを表すノードを通過した場合に当てはまります(その単語Wjを計算しましょう)。その場合、WjはWiのプレフィックスであり、ソリューションの一部です。
詳細(擬似コード):
for word in words
add word to trie
if size of trie did not change then // first case
add word to result
if ending nodes found while adding word // second case
add words defined by those nodes to result
return result
Trieに新しい単語を追加する:
node = trie.root();
for letter in word
if node.hasChild(letter) == false then // if letter doesnt exist, add it
node.addChild(letter)
if letter is last_letter_of_word then // if last letter of word, store that info
node.setIsLastLetterOf(word)
node = node.getChild(letter) // move
新しい単語を追加しているときに、他の単語の最後の文字を表すノードを通過したかどうかを確認することもできます。私が説明したアルゴリズムの複雑さはO(N)です。もう1つの重要なことは、この方法で、単語Wiが他の単語に接頭辞を付ける回数を知ることができることです。これは便利な場合があります。
{aab、aaba、aa}の例:緑のノードはケース1として検出されたノードです。赤のノードはケース2として検出されたノードです。各列(試行)は1つのステップです。最初はトライは空です。黒い矢印は、そのステップでアクセス(追加)したノードを示しています。ある単語の最後の文字を表すノードでは、その単語が括弧で囲まれています。

- ステップ1では、単語aabを追加します。
- ステップ2では、単語aabaを追加し、1つのケース2(単語aab)を認識して、結果に単語aabを追加します。
- ステップ3では、単語aaを追加し、ケース1を認識して、結果に単語aaを追加します。
最後に、正しい結果= {aab、aa}が得られます。