タイトルをわかりやすくするために変更しました。
これは質問の詳細なバージョンです:
文字列がs
あり、それを部分文字列に分割したいとします。各部分文字列は互いに異なります。1回のカットで取得できる一意の部分文字列の最大数はいくつですか。言い換えれば、formに連結する一意の部分文字列の最大数はいくつですかs
。
ここではいくつかの例を示します。
Example 1
s = 'aababaa'
output = 4
Explain: we can split `s` into aa|b|aba|a or aab|a|b|aa,
and 4 is the max number of substrings we can get from one split.
Example 2
s = 'aba'
output = 2
Explain: a|ba
Example 3
s = 'aaaaaaa'
output = 3
Explain: a|aa|aaaa
注:s
小文字のみが含まれます。どのくらいのs
時間がかかるかはわかりません。したがって、最適な時間の複雑さを推測することはできません。:(
NP難しい問題ですか?そうでない場合、どうすれば効率的に解決できますか?
友人からこの問題を聞いたが、答えられなかった。私はこの問題を解決するためにTrie +貪欲を使用しようとしています。最初の例では、メソッドは失敗します。
これが私が思いついたTrieソリューションです:
def triesolution(s):
trie = {}
p = trie
output = 0
for char in s:
if char not in p:
output += 1
p[char] = {}
p = trie
else:
p = p[char]
return output
それを分割しようとしているので、実施例1について、上記のコードは、3を返しますs
にa|ab|abaa
。
追加:みんなのアイデアのおかげで、この問題はNP問題に非常に近いようです。今、私はこの方向から考えようとしています。関数があるとしますGuess(n)
。この関数は、1つの分割などから一意の部分文字列をTrue
見つけた場合に返されます。ここでの観察の1つは、ifの場合、すべての場合です。2つの隣接する部分文字列をマージできるからです。この観察は、バイナリソリューションにつながる可能性があります。ただし、関数を非常に効率的に計算できる必要があります。悲しいことに、私はまだ計算する多項式の方法を見つけることができませんでした。n
False
Guess(n) == True
Guess(i) == True
i <= n
Guess
Guess(n)
a
またはb
?
aab|a|b|aa
まだ4のままです