Permutation Sequence
Permutation Sequence
[1,2,3,…,n] contains a total of n! unique permutations.We get the following sequence (ie, for n = 3):
"123""132""213""231""312""321"
Analysis:
One way to solve the problem (can only pass the small test) is to generate from the 1st permutation to the required one (similar to the problem Next permutation.). However, when n=9, the last permutation is the 362880th one, which is too time consuming.
A better way is to fully use the properties of permutation: the total number of permutation with length n is n!.
First, let's take a look at how permutation works:

Every leave node is a permutation. Take a look at the second level, each subtree (second lever node as the root), there are (n-1)! permutations in it. Totally there are n nodes in 2nd level, thus the total number of permutations are n*(n-1)!=n!.
So, what we wanna do is to locate one permutation among the leave nodes. The simple method is to generate and search each leave node until we find the one. Now, what we can do here we want to skip some trees to reduce the complexity. e.g. in the above tree, if we know the required leave node is in the third sub tree (under CBA), we can skip the first two and search from the "CBA".
Say we have the required permutation is the kth one, first we can locate which subtree it belongs to in the 2nd level, by computing s = k / ((n-1)!). Then we get the sth subtree, and set k=k%((n-1)!) , now search the sub tree until we get the leave node. How to get the sth subtree root node? Just like the idea of how permutation works (the first figure): Just put the sth elment after fixed letter. e.g. ABCD, we want the 3rd subtree root node in 2nd level, just put C in the 1st place, which is CABD; For ABCDE, we want the 3rd subtree root node in the 3rd level, it is ADBCE.
public class Solution { public String getPermutation(int n, int k) { int[] num = new int [n]; // count = !n int count = 1; for(int i = 0; i < n; i++){ num[i] = i+1; count *= (i+1); } // n是从1开始 所以kth个 的下标为 k-1 k--; StringBuilder sb = new StringBuilder(); for(int i = 0; i<n; i++){ // 第i层 每个节点下有多少种排列组合,注意 count是数组的下标,数组下标从 0 开始 count /= n-i; // 应该选第 i层的第几个,注意 selected 是数组的下标,数组下标从 0 开始 int selected = k / count; // 剪掉 第i层前面的, 得到新k k = k % count; sb.append(num[selected]); //restruct nums since one num has been picked for(int j = selected+1; j<n; j++){ num[j-1] = num[j]; } } return sb.toString(); } }
ref:http://yucoding.blogspot.com/2013/04/leetcode-question-68-permutation.html
http://www.cnblogs.com/feiling/p/3251230.html

浙公网安备 33010602011771号