要素の配列で表される順列が与えられた場合、間にあるすべての順列を計算せずに n 番目の順列を効率的に計算することは可能ですか?
答えは階乗分解にあります。並べ替えの辞書編集的な順序を考えてみましょう。順列のインデックスを階乗分数に分解することで、特定の順列を導き出すことができます。
このアプローチにより、ブルートフォース反復を必要とせずに、目的の順列に直接ジャンプできます。
たとえば配列 {A, B, C} を指定すると、サイズ 2 の 3 番目の順列の階乗分解は (2! * 0) (1! * 1) となります。 = (2 * 0) (1 * 1) = 1。これは、最初の要素 (B) とそれに続く 0 番目の要素 (A) に対応します。
次の C 実装は、この手法を示しています。
void ithPermutation(const int n, int i) { int *fact = (int *)calloc(n, sizeof(int)); int *perm = (int *)calloc(n, sizeof(int)); // Compute factorial numbers fact[0] = 1; for (int k = 1; k < n; k++) { fact[k] = fact[k - 1] * k; } // Compute factorial code for (int k = 0; k < n; k++) { perm[k] = i / fact[n - 1 - k]; i = i % fact[n - 1 - k]; } // Readjust values to obtain the permutation for (int k = n - 1; k > 0; k--) { for (int j = k - 1; j >= 0; j--) { if (perm[j] <= perm[k]) { perm[k]++; } } } // Print permutation for (int k = 0; k < n; k++) { printf("%d ", perm[k]); } printf("\n"); free(fact); free(perm); }
ithPermutation(10, 3628799) を呼び出すと、10 の最後の順列が返されます要素:
9 8 7 6 5 4 3 2 1 0
以上がブルートフォースなしでn番目の順列を効率的に見つけるにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。