**要求:**给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,
当 n = 3 时, 所有排列如下: "123" "132" "213" "231" "312" "321" 给定 n 和 k,
返回第 k 个排列。
示例:
输入:n = 3, k = 3 输出:"213"
输入:n = 4, k = 9 输出:"2314"
输入:n = 3, k = 1 输出:"123"
提示: 1 <= n <= 9 ,1 <= k <= n!
思路
全排列的排序结果和乘阶相关
看到 123和213的差别在第一位 其顺序也是相差2,
那么可以知道每一位对应的乘阶的差值之和与两数的顺序之差有关
取数123456789
213456789
很明显在第一位之后的所有数都是升序
可以总结思路
按照给定的k值 求得对应位数的乘阶差值 从最大位依次安排
若差值为零 则将剩余数字升序依次安排
若差值不为零 则将剩余数字升序加上差值的偏移量安排
代码
class Solution {
public String getPermutation(int n, int k) {
if(n==1)return "1";
int []num=new int[n+1];
k--;//1即0
//--------------------每位的乘阶差
for(int i=n;i>=1;i--){
int temp=math(i-1);
num[i]=k/temp;
k-=num[i]*temp;
if(k==0)break; }
//------------------数字的安排
int []fin=new int[n];
boolean []key=new boolean[n+1];
for(int i=n-1;i>=0;i--){
if(num[i+1]>0){
int temp=num[i+1];
for(int ii=1;ii<key.length;ii++)
if(key[ii]==false&&temp>0){temp--;}
else if(key[ii]==false&&temp==0){key[ii]=true;fin[i]=ii;break;}
} else if(num[i+1]==0){
for(int ii=1;ii<key.length;ii++)
if(key[ii]==false){fin[i]=ii;key[ii]=true;break;}}
}
//------------------输出
StringBuilder sb=new StringBuilder();
for(int i=n-1;i>=0;i--)sb.append(String.valueOf(fin[i]));
return sb.toString();
}
public int math(int n){
if(n==1)return 1;
return math(n-1)*n; }
}
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/pe… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。