题目链接:https://leetcode.com/problems/permutation-sequence/
方法1:回溯,及时停止。
这种思路好想,代码也好写。
注意当count==K时,不要把原有的list里面的对象删除了。
AC 313ms beats 12.5% Java :)速度感人
class Solution {
private int count=0;
private List<Integer> list =new ArrayList();
public String getPermutation(int n, int k) {
boolean[] flag=new boolean[n+1];
helper(n,k,flag);
StringBuilder sb=new StringBuilder();
for(int i : list){
sb.append(String.valueOf(i));
}
return sb.toString();
//return String.valueOf(list.size());
}
public void helper(int n,int k,boolean[] flag){
if(count==k){
return;
}
if(list.size()==n){
count++;
}
for(int i=1;i<=n&&count!=k;i++){
if(!flag[i]){
list.add(i);
flag[i]=true;
helper(n,k,flag);
flag[i]=false;
if(count!=k)
list.remove(list.size()-1);
}
}
return ;
}
}
方法二:找数学规律(逆康托排列)
由于二进制中 2的一次方对应0和1,依次类推,当我们拿到K时要先对K-1,
这样才能通过除法得到他正确的区间。
然后我们通过逆康托排列来求解第K个数每一位的值。
准备条件:分别求解出1到N-1的阶乘的值保存在数组中。
易错点: 对Java的list来说,get(0)表示取出第一个元素。
list的remove易错点:remove()方法陷阱。
有了这些准备条件,我们来尝试求解。
例1 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕
(1)找出第96个数
首先用96-1得到95,
用95去除4! 得到3余23,
有3个数比它小的数是4,
所以第一位是4,
用23去除3! 得到3余5,
有3个数比它小的数是4但4已经在之前出现过了所以第二位是5,
(4在之前出现过,所以实际比5小的数是3个)
用5去除2!得到2余1,
有2个数比它小的数是3,第三位是3,
用1去除1!得到1余0,
有1个数比它小的数是2,第二位是2,
最后一个数只能是1,
所以这个数是45321,
(2)找出第16个数
首先用16-1得到15,
用15去除4!得到0余15,
用15去除3!得到2余3,
用3去除2!得到1余1,
用1去除1!得到1余0,
有0个数比它小的数是1,
有2个数比它小的数是3 ,但由于1已经在之前出现过了所以是4,
(因为1在之前出现过了所以实际比4小的数是2)
有1个数比它小的数是2 ,但由于1已经在之前出现过了所以是3,
(因为1在之前出现过了所以实际比3小的数是1)
有1个数比它小得数是2 但由于1,3,4已经在之前出现过了所以是5,
(因为1,3,4在之前出现过了所以实际比5小的数是1)
最后一个数只能是2
所以这个数是14352
基本上例子看懂的话,程序不难写出来。
AC 6ms 99.96% Java:
class Solution {
public String getPermutation(int n, int k) {
List<Integer> list=new ArrayList();
int[] factorial=new int[n+1];
factorial[0]=1;
for(int i=1;i<=n;i++){
factorial[i]=factorial[i-1]*i;
list.add(i);
}
StringBuilder sb =new StringBuilder();
k--;//只需减一次即可。
for(int i=n;i>0;i--){
int temp=list.get(k/factorial[i-1]);
k=k%factorial[i-1];
if(i!=1){
sb.append(String.valueOf(temp));
list.remove(new Integer(temp));//如果不new一个Integer对象的话会出错。
}else{
sb.append(String.valueOf(list.get(0)));
}
}
return sb.toString();
}
}