古いチェコのアルゴリズムの教科書で次の問題に出会いましたが、悲しいことにヒントも解決策もありませんでした。
ように「我々はフィボナッチ列を定義、、、及び、一般的な文字であるが。どの所与のに文字列(潜在的に大きなアルファベットの上に)線形時間で最長のフィボナッチのサブワードを見つけることができますか?」F 1 = b F n + 2 = F n F n + 1 a b
私は二次時間で解決策を知っていますが、それを線形に減らすことはできません。誰かが私を正しい方向に向けることができますか?
古いチェコのアルゴリズムの教科書で次の問題に出会いましたが、悲しいことにヒントも解決策もありませんでした。
ように「我々はフィボナッチ列を定義、、、及び、一般的な文字であるが。どの所与のに文字列(潜在的に大きなアルファベットの上に)線形時間で最長のフィボナッチのサブワードを見つけることができますか?」F 1 = b F n + 2 = F n F n + 1 a b
私は二次時間で解決策を知っていますが、それを線形に減らすことはできません。誰かが私を正しい方向に向けることができますか?
回答:
明らかな方法は動的プログラミングです:順序フィボナッチ語が位置で始まる2文字を保存し、と。可能な値は対数的にしか存在しないため、これには最大で時間かかり。i j F (i − 2 、j )F (i − 1 、j + fib (i ))O (n log n )i
しかし、が空でない位置しか存在しないと思われます(つまり、同じ長さの2つのフィボナッチ語が存在する場合、ほとんどの長さではなく、長さの一定の割合まで重複しています)。空でない位置、あなたがのために(一定の時間)の計算を行うために必要のある唯一のものであり。私の疑いが真であれば、あなたはそれをスピードアップする可能性がの各値に対して空ではない位置のリストを追跡することにより、とするために、リストを使用してのためのリストの計算をスピードアップするために。F (i − 2 、j )F (i − 2 、j )F (i 、j )O (n )i i − 2 i
を配列に格納する場合、スペースは高速化後もままですが、代わりにハッシュテーブルを使用して改善できます。または、 -bit wordsのビットパック配列に格納することもできます(空かどうかだけを知る必要があるという観察を使用して、各部分文字列の2つの文字を見ることができます入力文字列内の最初の2つの位置)。O (n log n )Flog n