60. Permutation Sequence

一开始想用permutations那种全排列来计算,DFS写了好久发现人家n可以是9位数,递归几千万次这得什么计算机做得到。。

DFS(只能计算n很小的情况。。不可行)

String res = "";
public String getPermutation(int n, int k) {
   int[] count = new int[1];
   int[] num = new int[n];
   for (int i = 0; i < n; i++) {
      num[i] = i + 1;
   }
   backtracking(count, k, num, "", new boolean[num.length]);
   return res;
 
}
 
private void backtracking(int[] count, int k, int[] nums, String item, boolean[] used) {
   if (item.length() == nums.length) {
      if (++count[0] == k) {
         res = item;
      }
      return;
   }
   for (int i = 0; i < nums.length; i++) {
      if (!used[i]) {
         used[i] = true;
         backtracking(count, k, nums, item + nums[i], used);
         used[i] = false;
      }
   }
}

数学方法:

每次计算最高位的数字,用一个数组保存剩下的数字。index代表剩下的数字的位置。
index计算的方法是:
index = k / (n-1)!
这个index就表示,之前有index组个全排列(开头是同一个数字的一组全排列算是一组)
k就减去之前index * (n-1)!那么多个排列,再循环计算新的index即可。

    public String getPermutation(int n, int k) {
        int[] factorial = new int[n];
        factorial[0] = 1;
        for (int i = 1; i < n; i++) {
            //阶乘
            factorial[i] = i * factorial[i - 1];
        }
        List<Integer> nums = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            nums.add(i);
        }

        //k从0开始
        k--;
        StringBuilder res = new StringBuilder();
        for (int i = 1; i <= n; i++) {
            int index = k / factorial[n - i];
            res.append(nums.remove(index));
            k -= index * factorial[n - i];
        }
        return res.toString();
    }

推荐阅读更多精彩内容