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(); } }