觉得这道题有必要,我二次回顾,数学。。。。
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.
第一种解决办法,数学方法解决
//相当于因式分解
public String getPermutation(int n, int k) {
int[] factorial = new int[n];
//因式分解需要的基数
for (int i = 0; i < n; i++) {
if (i == 0) {
factorial[i] = 1;
continue;
}
factorial[i] = factorial[i - 1] * (i);
}
//1,1,2,6,24
//1*0+1*1+2*2+6*3+24*4=119
//而我们实际需要的数是:1、2、3、4、5,但他们的组合序列就相当于0、1、2、3、4的组合,只是各自加1而已。
//二者的不同还在于,0-4的k的表是范围是从0-119,而我们的k是从1-120,所以变换关系是k-1。
StringBuilder res = new StringBuilder();
boolean[] used = new boolean[n];
int i = n - 1;
while (i >= 0) {
int digit = (k - 1) / factorial[i];//变换关系k-1
res.append(findKth(used, digit));//先取最高位的值
k -= digit * factorial[i--];
}
return res.toString();
}
//再次强调下,数组是用的地址,而我们传递的对象就是普通的参数
public int findKth(boolean[] used, int digit) {
int res = -1;
while (digit >= 0) {
if (!used[++res]) { //从小到大的去取值,同时进行标记
digit--;
}
}
used[res] = true;
return res + 1;//从0-4,变为1-5
}
第二种方法,我的坑呀,每次都是先想到递归
首先只要两个元素换一下位置,就会使得count++的,假如我取得是1,那么剩下的【2、3、4、5】,再次进行重复的操作,还有的就是递归很容易超时,如何根据k值来减少重复,是很必要的,这个还可以优化,比如说不是用set,而是用上面的boolean[] used 下坐标和数值的位置关系。
public String getPermutation(int n, int k) {
String str = "";
TreeSet<Integer> set = new TreeSet<>();
for (int i = 1; i <= n; i++) {
str += i;
set.add(i);
}
if (k == 1 || n==1) {
//System.out.println(k +": "+ str);
return str;
}
str = "";
return getShort(set,k,str);
}
public int count;
public String getShort(TreeSet<Integer> set,int k,String str){
if(set.size()==2){
//System.out.println(str + set.first()+ set.last());
count ++;
if(count == k){
return str + set.first()+ set.last();
}
//System.out.println(str + set.last()+ set.first());
count ++;
if(count == k){
return str + set.last()+ set.first();
}
return null;
}else{
Object[] array = set.toArray();
for(int i=0;i<array.length;i++){
Integer t = (Integer)array[i];
set.remove(t);
str=str+t;
int z = count;
String ret = getShort(set,k,str);
if(count == k){
return ret;
}
set.add(t);
str=str.substring(0, str.length()-1);
if(k>(z+((array.length)*(count-z)))){
count =z+array.length * (count-z);
i=array.length-1;
}
}
return null;
}
}
我想过用set的迭代器遍历所有值,但是不可以,我觉得应该和我这个迭代冲突了,我也不知道为啥,一上午终于解决这个问题了。