题目大意:找出n的全排列中的第k个排列。
法一:DFS,遍历前k个排列,输出,超时。代码如下:
1 public String getPermutation(int n, int k) { 2 List<Integer> tmp = new ArrayList<Integer>(); 3 String res = ""; 4 List<List<Integer>> list = new ArrayList<List<Integer>>(); 5 res = dfs(list, n, k, tmp, res); 6 return res; 7 } 8 public static String dfs(List<List<Integer>> list, int n, int k, List<Integer> tmp, String res) { 9 if(list.size() > k) { 10 return res; 11 } 12 if(tmp.size() == n) { 13 list.add(new ArrayList<Integer>(tmp)); 14 if(list.size() == k) { 15 for(int i = 0; i < tmp.size(); i++) { 16 res += tmp.get(i); 17 } 18 } 19 return res; 20 } 21 for(int i = 1; i <= n; i++) { 22 if(!tmp.contains(i)) { 23 tmp.add(i); 24 res = dfs(list, n, k, tmp, res); 25 tmp.remove(tmp.size() - 1); 26 } 27 } 28 return res; 29 }
法二(借鉴):数学规律,具体,代码如下(耗时17ms):
1 public String getPermutation(int n, int k) { 2 List<Integer> num = new LinkedList<Integer>(); 3 for(int i = 1; i <= n; i++) { 4 num.add(i); 5 } 6 int[] fact = new int[n]; 7 fact[0] = 1; 8 //计算阶层 9 for(int i = 1; i < n; i++) { 10 fact[i] = i * fact[i - 1]; 11 } 12 k = k - 1; 13 //由于要经常+字符串,所以弃用String,这样可以加快效率 14 StringBuilder res = new StringBuilder(); 15 for(int i = n; i > 0; i--) { 16 //第i位应该放置的第pos个数,这个pos是原1-n中的位置 17 int pos = k / fact[i - 1]; 18 k = k % fact[i - 1]; 19 //正确放置 20 res.append(num.get(pos)); 21 //已经放置过了就删除 22 num.remove(pos); 23 } 24 return res.toString(); 25 }