Permutation Sequence
Total Accepted: 3033 Total Submissions: 14751 My Submissions
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):
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
1、第一种思路,我一眼看到这种,就想到DFS,暴力搜索嘛,搜到所有的答案之后,放到list中,
题目不是要求第K个组合是多少么,从list中get就得到了。超时。
Java代码
public class Solution {
public String getPermutation(int n, int k) {
ArrayList<String> list = new ArrayList<String>();
for(int i = 1; i <= n; i++){
StringBuffer sb = new StringBuffer(i);
int visit[] = new int[n+1];
visit[i] = 1;
sb.append(i);
int num = 1;
dfs(list,visit,sb,n,num);
}
return list.get(k-1);
}
public void dfs(ArrayList<String> list, int visit[], StringBuffer sb, int n, int num){
if(num == n){
list.add(sb.toString());
}
for(int i = 1; i <= n; i++){
if(visit[i] == 0){
StringBuffer tempSb = new StringBuffer(sb);
tempSb.append(i);
visit[i] = 1;
dfs(list,visit,tempSb,n,num+1);
visit[i] = 0;
}
}
}
}
2、优化第一种,还是DFS,我不罗列所有的了,每次得到一个答案,就判断当前个数是不是和k相等,
如果相等的话,就把得到的结果return回去。还是超时了,不过好像比第一种多过了几个case。
Java代码
public class Solution {
public int count ;
public String result;
public String getPermutation(int n, int k) {
count = 0;
result = "";
for(int i = 1; i <= n; i++){
StringBuffer sb = new StringBuffer(i);
int visit[] = new int[n+1];
visit[i] = 1;
sb.append(i);
int num = 1;
dfs(visit,sb,n,num,k);
}
return result;
}
public void dfs(int visit[], StringBuffer sb, int n, int num, int k){
if(num == n){
count ++;
if(count == k){
result = sb.toString();
return;
}
}
for(int i = 1; i <= n; i++){
if(visit[i] == 0){
StringBuffer tempSb = new StringBuffer(sb);
tempSb.append(i);
visit[i] = 1;
dfs(visit,tempSb,n,num+1,k);
visit[i] = 0;
}
}
}
}
3、数学规律。我又一次的发现了,我不是什么高手。但是我要努力成为大牛。还很远,慢慢努力吧。
扯远了,还是说代码。
其实学过数学,知道排列组合,无重复数据的话,n个数,从1到n就有n!种组合。
那么如果我们知道第一位数字是多少,就能算出后面的(n-1)位数的组合,也就是(n-1)!种组合。
这个分析很明显了,n可以分成n组,每组有(n-1)!个数,
比如n = 6,那么以1,2,3,4,5,6开头的组合必然是各有(n-1)! = 5! = 120中组合。
我们认为组数应该从0开始,那么k要-1;
注意此时K = 299,那么我们先要求解这个k在第几组,k/(n-1)! = 299/120 = 2,也就是说k应该在第
3组(注意组号从0开始),第三组的首个数字应该是3。这样第一个数字就确定了。
确定第2个数字的时候,注意这个时候,k应该等于k % 120 = 59,为什么要这么算呢,因为每个组有120个数字,
而且k在第三组,那么前两组加起来是240,k在第二次循环的时候,应该是从(5-1)!中确定是属于哪个组,其实
就是确定k在第三组中是属于哪个位置。这个时候59/24 = 2,确定应该是属于第三组,
因为在上一步中,3已经用过了,所以这个时候的5个数字是1,2,4,5,6,
所以第三组的首个数字是4,依次类推,一直到n个数字全部算完为止。
答案就出来了。
Java AC
public class Solution {
public String getPermutation(int n, int k) {
List<Integer> numList = new ArrayList<Integer>();
numList.add(1);
int sum = 1;
for(int i = 2; i <= n; i++){
sum *= i;
numList.add(i);
}
sum /= n;
k--;
StringBuffer sb = new StringBuffer();
for(int i = 1; i <= n; i++){
int currNum = k / sum;
sb.append(numList.get(currNum));
numList.remove(currNum);
if (i == n) {
break;
}
k %= sum;
sum /= (n-i);
}
return sb.toString();
}
}