LeetCode 60 _ Permutation Sequence 置换序列
Description:
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:
"123"
"132"
"213"
"231"
"312"
"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"
Solution:
这道题让我们求出由1, 2, ... n按大小顺序排列组成的全排列中第k位的数
观察题目中给出的例子,我们可以看到在n=3时,由1开头的数共有2个,由后两位互换位置得到,2与3相同。
我们再观察由1~4组成的全排列,当第一位为1时,有如下几种情况:
“1234”
“1243”
“1324”
“1342”
“1423”
“1432”
一共有6种情况。
当第一位固定时,全部情况即为剩下的三个数(2.3.4)进行全排列的所有情况,而这三位数的排列实际上也可以分为固定第二位,再对第三、四位进行排列。
对三、四位排列共有2种情况,乘上第二位的3种情况(2.3.4),即为三位数的全排列总数。
由以上情况我们可以推断出,剩下i位数所占的情况数为:i * (i-1) * ... * 1
解题的思路:根据题目给出的所需求的位数k以及每一位数的总情况数,依次获得第1,2,...n位数。
例如题目中给出的例子,n=4,k=9时,1,2,3,4开头每个共有6种情况,6<k<12,可确定第一位为2。
再以第一位为2为基础,查看它的所有情况,1,3,4开头每个共2中情况,2<k'<4,可确定第二位为3。
依次类推,得到最后结果。
有一点需要留意的时,题目中给出的k,为从1开始计算,因此如果需要在循环中使用,要先将k-1,才能得到正确答案。
重新做的时候发现一个问题,不宜使用k作为循环判断的标志,因为当k=1的时候会陷入死循环……还是用n比较直接!!
Code:
public String getPermutation(int n, int k) { List<Integer> ori = new ArrayList<>(); //store the origin number int[] factorial = new int[n+1]; factorial[0] = 1; for (int i = 1; i <= n; i++){ ori.add(i); // produce the origin number factorial[i] = factorial[i-1]*i; // produce the factorial series } // produce the result StringBuilder res = new StringBuilder(); k = k -1; while (n > 0){ int index = k / factorial[n-1]; k -= index * factorial[n-1]; res.append(ori.get(index)); ori.remove(index); n--; } return String.valueOf(res); }
提交情况:
Runtime: 1 ms, faster than 100.00% of Java online submissions for Permutation Sequence.
Memory Usage: 36 MB, less than 100.00% of Java online submissions for Permutation Sequence.
这情况不禁让我纳闷了,难道计数坏了么,怎么最近这俩都是100%,100%?这个算法好像没啥巧的……?