質問はクエリの数をにする動機にはなりません。一意の可能なクエリの数は順序付けられたペアの数、つまりため、これは任意の最悪のケースのようです。O (n )O (ん2)
以下は、Ukkonenのアルゴリズムを使用して増分的に構築された(暗黙の)サフィックスツリーに基づく場合の時間の複雑性がより優れた2つの異なるソリューションです。両方の溶液は、前処理に基づいており、複雑有するクエリの集合です。2番目のソリューションは、すべてのクエリの幅が同じである場合、実行されます。O (ん2)O (ん2+ | Q | )QO (n + | Q |)
解決策1-すべての一意のクエリを前処理する
のサフィックスを反復処理します。各サフィックス、Ukkonenのアルゴリズムを使用してのサフィックスツリーをします。を現在のサフィックスツリーに更新した後、ツリーサイズを行列の位置に格納します。範囲のクエリは、行列要素によって応答されます。SS私= S[ i 。。n ]S私j(i 、i + j − 1 )[ x 、y](x 、y)
接尾辞ツリーのサイズは接尾辞ツリーと一緒に保存でき、Ukkonenのアルゴリズムの更新手順を変更することにより、各ステップで一定の時間で更新できます。更新ごとに、サイズは現在の葉の数だけ増加します。
解決策2-一意のクエリ幅を前処理する
このソリューションは実装が困難ですが、クエリの幅が少ない場合は前処理作業が少なくて済みます。クエリ幅が1つしかない場合、前処理には時間かかります。O (n )
クエリの幅ごとに、幅スライディングウィンドウを使用して、サフィックスツリーを段階的に構築します。ツリーから最も長いサフィックスを削除して、ウィンドウの左側の1文字から始まるサフィックスを削除します。各ステップで、スライディングウィンドウ内の現在の部分文字列の数はツリーのサイズです。ww
その後、事前計算の結果を使用して、すべてのクエリに線形時間で応答できます。
注:最長のサフィックスを削除するには、サフィックスツリーの最も古いリーフを削除します。正しく実装するのは簡単ではありません。