给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

"123"

"132"

"213"

"231"

"312"

"321"

给定 n 和 k,返回第 k 个排列。

说明:

给定 n 的范围是 [1, 9]。

给定 k 的范围是[1,  n!]。

示例 1:

输入: n = 3, k = 3

输出: "213"

示例 2:

输入: n = 4, k = 9

输出: "2314"

答案

 1public String getPermutation(int n, int k) {
2    List<Integer> num = new LinkedList<Integer>();
3    for (int i = 1; i <= n; i++) 
4        num.add(i);
5    int[] fact = new int[n]; 
6    fact[0] = 1;
7    for (int i = 1; i < n; i++) 
8        fact[i] = i * fact[i - 1];
9    k = k - 1;
10    StringBuilder sb = new StringBuilder();
11    for (int i = n; i > 0; i--) {
12        int ind = k / fact[i - 1];
13        k = k % fact[i - 1];
14        sb.append(num.get(ind));
15        num.remove(ind);
16    }
17    return sb.toString();
18}

解析:

上面数组fact的值也就是阶乘的值,集合n中有n的阶乘种组合。比如当n=4,k=14的时候,

1(2,3,4),1+(2,3,4)的全排列,有6种,

2(1,3,4),同理都有6种组合,

3(1,2,4),也有6种组合,但是前面的两种已经到12了,所以这里只需要2种组合就行了,也就是31+(2,4)的两种排列组合,正好加起来是14,其中第13个是3124,第14个是3142,所以结果是3142。

看了上面的例子,我们再来分析这道题,其实这道题应该算是一道数学题。

因为最终结果是k位,我们从第一位开始找,第一位也就是index = k / (n-1)!,(n-1)!也就是去掉最前面的那位之后,后面的几种排列组合(参照上面的分析),其中(n-1)!是fact(n-1)的阶乘,找到第一位之后,k值就要更新,变为k = k%(n-1)!,这个也很好理解,同理然后再找第二位,也就是index = k / (n-2)!……如果对排列组合不是很熟悉的话,理解起来可能会有些费劲。下面再来看一种写法。

 1public String getPermutation(int n, int k) {
2    k--;
3    int fact = 1;
4    char[] result = new char[n];
5    result[n - 1] = '1';
6    for (int i = 2; i <= n; i++) {
7        fact *= i;
8        result[n - i] = (char) (k % fact * i / fact + '1');
9        for (int j = n - i + 1; j < n; j++) {
10            result[j] += result[j] >= result[n - i] ? 1 : 0;
11        }
12        k -= k % fact;
13    }
14    return new String(result);
15}

这个解法稍微有点烧脑了,第一个方法是从第一位开始往后找,这个方法是从最后一位往前找,这个k个长度的字符串可以用下面这个公式来表示

(n-1)!*A[0] + (n-2)!*A[1] + ... + 2!*A[n-3] + 1!A[n-2] + 0!A[n-1]并且0 <= A[i] < n-i 

这个公式很容易推导,也很好理解,比如说第一位也就是上面说的index = k / (n-1)!,所以反过来不就是k= index *(n-1)!吗,同理,后面的也都一样……

很明显0!A[n-1]是等于0的,因为0<=A[n-1]<1,所以A[n-1]只能是0,所以我们可以令最后一个元素result[n - 1] = '1';从后往前推。(注意n是从1开始的,而我们的数组下标是从0开始的)