次の質問が突然関連しているように見えたとき、私はプログラミングの質問を調べていました。
次のように少ないスワップを使用して、文字列を別の文字列に変換するにはどうすればよいですか。文字列は相互変換可能であることが保証されています(同じ文字セットがあり、これが指定されています)、ただし、文字は繰り返すことができます。同じ質問でウェブの結果を見ましたが、文字は繰り返されていません。文字列内の任意の2文字を交換できます。
たとえば、「aabbccdd」は2回のスワップで「ddbbccaa」に変換でき、「abcc」は1回のスワップで「accb」に変換できます。
ありがとう!
「差分」文字列S
およびS'
を作成できます。つまり、2つの文字列の異なる位置にある文字を含む文字列です。 acbacb
およびabcabc
の場合、cbcb
およびbcbc
になります。これにn文字が含まれているとしましょう。
これで、n
ノードと、S[i] == S'[j]
の場合はi
からj
までのエッジを持つ「順列グラフ」Gを作成できます。すべての一意の文字の場合、必要なスワップの数は(n-Gのサイクル数)であることが簡単にわかります。これは、O(n)時間。
ただし、重複する文字がいくつもある場合、これは有向グラフで最大のサイクル数を見つけるという問題になります。これは、NP困難だと思います(例:チェックアウト: http://www.math.ucsd.edu/~jverstra/dcig.pdf )。
その論文では、いくつかの欲張りアルゴリズムが指摘されており、そのうちの1つは特に単純です。
ただし、ケースのプロパティを利用する効率的なアルゴリズムがある場合があります(私が考えることができるのは、グラフがK-partiteになることだけです。ここで、KはS
内の一意の文字の数です)。幸運を!
編集:問題のより完全で正しい説明については、Davidの回答を参照してください。
ハッシュマップデータ構造(重複を許可する)は、問題の解決に適しています。
文字列をs1とs2とします。アルゴリズムは文字列の両方を反復処理し、不一致が見つかると、アルゴリズムはs1の文字をs2にマップします。つまり、不一致が発生した場合は常に、s1の文字をキーとして、s2の文字を値としてハッシュマップに挿入します。
この後、結果をゼロとして初期化します。
次のステップは、ハッシュマップが空でないときに次の手順を実行することです。
結果は、希望する出力を保持します。
ある文字列から別の文字列への同等の文字列のグラフを通る最短パスについて、A *検索を実行します(説明については http://en.wikipedia.org/wiki/A-star_search_algorithm を参照)。コストヒューリスティックとしてレーベンシュタイン距離/ 2を使用します。