K番目順列アルゴリズム解析

数学的アプローチによる効率的な順列計算

時間計算量: O(n²) 空間計算量: O(n)

TypeScript実装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                                        
function getPermutation(n: number, k: number): string {
    // 階乗を事前計算
    const factorial: number[] = [1];
    for (let i = 1; i < n; i++) {
        factorial[i] = factorial[i - 1] * i;
    }
    
    // 使用可能な数字のリスト
    const numbers: number[] = [];
    for (let i = 1; i <= n; i++) {
        numbers.push(i);
    }
    
    // k を 0-indexed に変換
    k--;
    
    let result: string = '';
    
    // 各桁を順番に決定
    for (let i = 0; i < n; i++) {
        // インデックス計算
        const index: number = Math.floor(k / factorial[n - 1 - i]);
        
        // 数字を結果に追加
        result += numbers[index];
        
        // 使用済み数字を削除
        numbers.splice(index, 1);
        
        // k を更新
        k %= factorial[n - 1 - i];
    }
    
    return result;
}                                       
                                    

アルゴリズム概要

核心アイデア

全順列を生成せず、数学的計算で直接k番目の順列を求める

キーポイント

  • • 階乗による位置計算
  • • 各桁での数字選択
  • • 使用済み数字の除去
  • • 剰余演算での位置更新

効率性

O(n!)の全順列生成を回避し、O(n²)で直接計算