力扣60题--第k个排列

60.给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

示例 1:

输入: n = 3, k = 3
输出: "213"
示例 2:

输入: n = 4, k = 9
输出: "2314"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutation-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:
给定常数n,共有n!种排列组合,可以将其分成n组,则每组就有(n-1)!个,
然后需要输出的第k个,确定当前数位于第几组,并求出在该组的第几个;
计算 k 除以 (n-1)! = shang…yu
则 组数 groupIndex = shang +(yu >0? 1: 0)
在下一组的偏移量:若余数不为0,则与偏移量就是余数,否则偏移量就是 (n-1)!
确定组数,就可以确定当前位置的数(在未使用的数的排列种第 groupIndex 就是当前位置的数)
然后将下个位置的偏移量以及(n-1)!继续传入,用上述方法,继续确定下一个位置的数字,此时就会用到递归。

代码:

class Solution {
     
    public String getPermutation(int n, int k) {
     
       //flag数组记录当前的值是否可用
        boolean[] flag = new boolean[n];
        //2.需要知道(n-1)!的值
        int res = 1;
        for (int i = 1; i < n; i++) {
     
            res *= i;
        }
        //这里直接nerStringBuilder
        StringBuilder sb = new StringBuilder("");
        //3.此时应该调用函数dfs(n,(n-1)!, k(偏移量), flag),最终返回一个字符串
        dfs(n, res, k, flag, sb);
        return sb.toString();   
    }
    void dfs(int n, int f, int k, boolean[] flag,StringBuilder sb) {
     
        //首先根据传入的k,和 (n-1)!确定当前位置的数应该在第几组,并且确定下一个位置的偏移量
        int shiftNext = k % f;
        int group = k / f+(shiftNext ==0 ? 0: 1);
        if (shiftNext == 0) {
     
            shiftNext = f;
        }
        //通过以下for循环,得到第group个没有被使用的数,也就是当前位置的值i,并应该将当前位置的flag设置为true
        int i = 0;
        for(; i<flag.length && group>0; i++) {
     
            if (!flag[i]) {
     
                group--;
            }
        }
        flag[i-1] = true;
        sb.append(i);
        if(n == 1) {
     
            return ;
        }else {
     
            dfs(n-1, f/(n-1), shiftNext, flag, sb);
        }
    }
    

}

你可能感兴趣的:(力扣刷题算法)