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 (ie, 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.
Solution1
- 最简单的方法,或者说最容易想到的方法是利用Leetcode31 Next Permutation的方法来一个一个求得,直到求到第k个为止。
import java.util.Arrays;
public class Solution {
public String getPermutation(int n, int k) {
int[] perm = new int[n];
int total = 1;
for(int i=1;i<=n;i++){
perm[i-1] = i;//这里边界出错了
total *= i;
}
k %= total;
if(k==0) k = total;
int count = 0;
while(true){
count++;
if(count==k) break;
int i;
for(i=n-1;i>0;i--){
if(perm[i]>perm[i-1]){
int temp = perm[i-1];
int j;
for(j=n-1;j>i&&perm[j]<temp;j--);
perm[i-1] = perm[j];
perm[j] = temp;
break;
}
}
for(int m=i,j=n-1;m<j;m++,j--){
int temp = perm[j];
perm[j] = perm[m];
perm[m] = temp;
}
}
StringBuffer sb = new StringBuffer();
for(int num:perm) sb.append(num);
return sb.toString();
}
}
Solution2
- 解法一思路清晰,但时间复杂度高,需要一个一个的求下个排列。实际上,针对n=4,k=17来说,答案是”3412”,可以这样考虑,因为要从0开始数,所以先把 k−− ,以1和2为开头的排列个数都为 (n−1)!=6 ,因此 k/(n−1)!=16/6=2 ,由此可以得到第一个数为 (2+1)=3 ,然后还剩下 16%6=4 . 这里同样可以按照上述思路以此类推。
public class Solution {
public String getPermutation(int n, int k) {
if(n<1||k<1) return "";
StringBuffer sb = new StringBuffer();
int div = 1;
for(int i=1;i<n;i++) div *= i;//求得(n-1)!
if(k>div*n) return "";//K超出范围了
k--;
int[] digits = new int[n];
for(int i=0;i<n;) digits[i++] = i;
while(true){
sb.append(digits[k/div]);
for(int i=k/div;i+1<n;i++) digits[i] = digits[i+1];//将后面的数前移,实际上是删除当前的数
k %= div;
if(--n==0) break;
div /= n;
}
return sb.toString();
}
}
Solution3
- 解法二中的删除当前的数可以有更好的办法。
public class Solution {
public String getPermutation(int n, int k) {
if(n<1||k<1) return "";
StringBuffer sb = new StringBuffer();
int div = 1;
List<Integer> digits = new ArrayList<Integer>();
for(int i=1;i<n;i++) div *= i;//求得(n-1)!
for(int i=1;i<=n;i++) digits.add(i);
if(k>div*n) return "";//K超出范围了
k--;
while(true){
sb.append(digits.remove(k/div));//用List来删除更方便,不用挪后面的数
k %= div;
if(--n==0) break;
div /= n;
}
return sb.toString();
}
}