[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.

Example 1:

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

Example 2:

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

第K个排列。题意是给你一个数字N(比如N = 3),如果输出1到N的全排列,结果会是类似这样,

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

现在给你一个数字N和一个数字K,请你输出的是这个全排列里面的第K项。

我参考了LC讨论区的最高票答案。他的思路基本上是逐位确定每一位上应该是什么数字,然后再一点点append起来的。首先如果N = 4,那么也就是有1,2,3,4四个数字,他的permutation应该类似如下这样,同时4的全排列的总数是4! = 24

  • (0)1 + {2, 3, 4的全排列} = 6
  • (1)2 + {1, 3, 4的全排列} = 6
  • (2)3 + {1, 2, 4的全排列} = 6
  • (3)4 + {1, 2, 3的全排列} = 6

如果给你一个数字N,你很容易就知道这N个数字的全排列的个数是N!。同时如果你知道全排列里面第一个数字的话,那么你接下来也只需要在(N - 1)! 个结果中就能确定你这个全排列到底是什么了。这月就是为什么这个题能逐位确定每一位上应该是什么数字的原因。

还是假设N = 4,那么全排列的个数是4! = 24;如果你能确定第一个数字的话,那么你可以将要找的范围缩小到三个数字的全排列,即3! = 6。但是如何得知第一个数字呢?假如你要找的K = 14,先将K--,得到13(因为数组中的index一般是从0开始的)。K / (N - 1)! = K / 3! = 13 / 3! = 13 / 6 = 2,意味着第一个数字的index = 2,也就意味着第一个数字其实是3

知道第一个数字是3之后,也就知道了接下来是在{1, 2, 4的全排列}里面找结果了。如果一直递归地往下想,要找的也就是

(0)1 + {2, 4的全排列} = 2

(1)2 + {1, 4的全排列} = 2

(2)4 + {1, 2的全排列} = 2

但是此时K已经不是13了,而是K % (N - 1)! = 13 % 3! = 13 / 6 = 1。

下一轮K / (N - 1)! = 1 / 2! = 1 / 2 = 0,意味着第二个数字的index = 0,第二个数字是1是在1 + {2, 4的全排列}里面接着找。此时K = K % (N - 1)! = 1 % 2! = 1 % 2 = 1。

此时在3 + {1, 2, 4的全排列}里面继续找。既然K = 0,那么在3 + 1 + {2, 4的全排列}里面的index又是多少呢?

第三个数字的index = K / (N - 1)! = 1 / 1! = 1,意味着第三个数字的index = 2第三个数字是1,下一轮因为只剩一个数字2,所以结果就是3142。

时间O(n^2)

空间O(n)

Java实现

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

LeetCode 题目总结

猜你喜欢

转载自www.cnblogs.com/cnoodle/p/13171282.html