求所有排列中的第 i 个排列的问题

[LeetCode 60] Permutation Sequence

题目

The set [1,2,3,...,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order, we get the following sequence for n = 3:

1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "321"
Given n and k, return the kth permutation sequence.

Note:
Given n will be between 1 and 9 inclusive.
Given k will be between 1 and n! inclusive.

测试案例

Input: n = 3, k = 3
Output: "213"

Input: n = 4, k = 9
Output: "2314"

思路

已知以1开头的序列编号范围是:1 ~ (n - 1)!;以 2 开头的序列编号范围是:(n - 1)! + 1 ~ 2(n-1)! …… 以 p 开头的序列编号范围是: 1 + (p - 1)(n - 1)! ~ p(n - 1)!。从中可以发现,当待排序长度为 n 时:

[开头数字的序号为 = (k - 1)/(n - 1)! + 1 ]

代码如下

class Solution {
    public String getPermutation(int n, int k) {
        int[] factor = new int[n];        
        factor[0] = 1;                
        for(int i = 1; i < n; i++){                      
            factor[i] = factor[i - 1] * i;
        }
        int[] val = new int[n + 1]; 
        for(int i = 1; i <= n; i++){
            val[i] = i;
        }
        k--;
        for(int i = 1, index; i <= n; i++){            
            index = k / factor[n - i] + i;
            val[0] = val[index];
            while(index > i){
                val[index] = val[index - 1];
                index--;
            }
            val[i] = val[0];
            k %= factor[n - i];
            if(k == 0){
                break;
            }
        }
        StringBuilder sb = new StringBuilder();
        for(int i = 1; i <= n; i++){
            sb.append(val[i]);
        }
        return sb.toString();
    }
}

思路2

查询剩余字符中第 i 号字符时,可以采用平衡树存储。这样每次查找的时间复杂度为 (O(lgn))。只是实现比较复杂。

原文地址:https://www.cnblogs.com/echie/p/9594333.html