问题描述
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3
输出: "213"
示例 2:
输入: n = 4, k = 9
输出: "2314"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutation-sequence
解答
/* 以''开头的的排列有n!个 以1开头的排列有(n-1)!个,若k<(n-1)!,则排列以1开头,若(n-1)!<k<2*(n-1)!,则排列以2开头.... 以此类推 .... .... */ class Solution{ public String getPermutation(int n, int k) { int[] factorial = new int[]{1,1,2,6,24,120,720,5040,40320};//0-8的阶乘 StringBuilder res = new StringBuilder(); boolean[] used = new boolean[n+1];//表示元素用过没有 for(int i=n-1;i>0;i--){ int a = k/factorial[i]; int r = k%factorial[i]; if(r != 0){ a++; k = r; }else{ k = factorial[i]; } for(int j=1;j<=n;j++){ if(!used[j])a--; if(a==0){ res.append(j); used[j] = true; break; } } } for(int i=1;i<=n;i++)if(!used[i])res.append(i); return res.toString(); } } /*超时的递归。。 class Solution { Set<Integer> res; List<Integer> result; int k, n, flag; public void dfs(List<Integer> output){ if(flag!=0)return; if(n == res.size()){ //System.out.println("set:"+output+"idx:"+idx); if(--k==0){ result = new ArrayList<Integer>(output); flag = 1; } return; } for(int i=1;i<=n;i++){ if(!res.add(i))continue; //System.out.println("set:"+output); output.add(i); dfs(output); res.remove(i); output.remove(output.size()-1); } } public String getPermutation(int n, int k) { this.k = k; this.n = n; flag = 0; res = new HashSet<Integer>(); result = new ArrayList<Integer>(); dfs(new ArrayList<Integer>()); StringBuilder sb = new StringBuilder(); for(int i:result)sb.append(i); return sb.toString(); } } */