長さの二つの文字列kは、一つの文字が異なる長さのプレフィックスを共有Lと長さのサフィックスMようにK = L + M + 1。
サイモン・プリンスによって答えは、すべての接頭辞/接尾辞の組み合わせ明示的に格納することで、これを符号化し、すなわちabc
なり*bc
、a*c
とab*
。それはk = 3、l = 0,1,2およびm = 2,1,0です。
valarMorghulisが指摘しているように、プレフィックスツリーで単語を整理できます。非常によく似た接尾辞ツリーもあります。各プレフィックスまたはサフィックスの下にあるリーフノードの数でツリーを拡張するのはかなり簡単です。これは、新しい単語を挿入するときにO(k)で更新できます。
これらの兄弟カウントを必要とする理由は、新しい単語が与えられると、すべての文字列を同じプレフィックスで列挙するか、すべての文字列を同じサフィックスで列挙するかを知るためです。たとえば、入力としての「abc」の場合、可能な接頭辞は「」、「a」、および「ab」であり、対応する接尾辞は「bc」、「c」、および「」です。明らかなように、短い接尾辞については、接頭辞ツリーの兄弟を列挙する方が適切です。逆も同様です。
@einpoklumが指摘しているように、すべての文字列が同じk / 2プレフィックスを共有する可能性は確かにあります。これはこのアプローチの問題ではありません。プレフィックスツリーは深さk / 2まで線形で、最大k / 2深さまでの各ノードが100.000リーフノードの祖先です。その結果、接尾辞ツリーは(k / 2-1)の深さまで使用されます。これは、接頭辞を共有する場合、文字列の接尾辞が異なる必要があるためです。
[編集]最適化として、文字列の最短の一意のプレフィックスを決定すると、1つの異なる文字がある場合、それがプレフィックスの最後の文字である必要があることがわかります。 1つ短いプレフィックスをチェックします。したがって、「abcde」に最短の一意のプレフィックス「abc」がある場合、「ab?」で始まる他の文字列があることを意味します。「abc」ではありません。つまり、1文字だけが異なる場合、それはその3番目の文字になります。もう「abc?e」を確認する必要はありません。
同じロジックで、「cde」が一意の最短接尾辞であることがわかった場合、長さ1または3の接頭辞ではなく、長さ2の「ab」接頭辞のみをチェックする必要があることがわかります。
この方法は、正確に1文字の違いに対してのみ機能し、2文字の違いには一般化されないことに注意してください。1つの1文字が同一のプレフィックスと同一のサフィックスを区別することに依存します。