leetcode60 排列序列

199 阅读1分钟

**要求:**给出集合 [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… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。