文字列に対する次の関数を検討してください。
int F(string S)
{
int N = S.size();
int T = 0;
for (int i = 0; i < N; i++)
for (int j = i + 1; j < N; j++)
if (S[i] > S[j])
T++;
return T;
}
長さ N の文字列 S0 には、すべての対ごとに異なる文字があり、合計 N! ユニークな順列。
たとえば、「bac」には次の 6 つの順列があります。
bac
abc
cba
bca
acb
cab
これらのNを考えてみてください!辞書順の文字列:
abc
acb
bac
bca
cab
cba
次に、これらの文字列のそれぞれに F を適用することを検討してください。
F("abc") = 0
F("acb") = 1
F("bac") = 1
F("bca") = 2
F("cab") = 2
F("cba") = 3
この一連の順列の一部の文字列 S1 が与えられた場合、次の文字列 S2 をセット内で見つけたいと考えています。これは、S1 と次の関係があります。
F(S2) == F(S1) + 1
たとえば、S1 == "acb" (F = 1) の場合、S2 == "bca" (F = 1 + 1 = 2) よりも
これを行う 1 つの方法は、S1 の 1 つ前から開始し、F(S) = F(S1)+1 を探して順列のリストを反復処理することです。これは残念ながら O(N!) です。
S1 のどの O(N) 関数によって、S2 を直接計算できますか?