ホームページ > バックエンド開発 > PHPチュートリアル > ブルートフォースなしでn番目の順列を効率的に見つけるにはどうすればよいでしょうか?

ブルートフォースなしでn番目の順列を効率的に見つけるにはどうすればよいでしょうか?

Patricia Arquette
リリース: 2024-12-06 20:49:10
オリジナル
602 人が閲覧しました

How Can We Efficiently Find the nth Permutation Without Brute Force?

総当たりなしで n 番目の順列を見つける

要素の配列で表される順列が与えられた場合、間にあるすべての順列を計算せずに n 番目の順列を効率的に計算することは可能ですか?

答えは階乗分解にあります。並べ替えの辞書編集的な順序を考えてみましょう。順列のインデックスを階乗分数に分解することで、特定の順列を導き出すことができます。

  1. 最も高い階乗から順に、階乗数を使用して因数分解を実行します。
  2. 商は次のとおりです。順列配列内のインデックス。以前の値が等しいかそれより低い可能性があることを考慮して値を調整します。

このアプローチにより、ブルートフォース反復を必要とせずに、目的の順列に直接ジャンプできます。

たとえば配列 {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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート