LeetCode 60 Permutation Sequence (数学)

来源:互联网 发布:旧金山和奥克兰 知乎 编辑:程序博客网 时间:2024/06/05 19:36

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

题目链接:https://leetcode.com/problems/permutation-sequence/description/

题目分析:最无脑的方法就是next_permutation执行k次,迭代写可能能过,下面解释直接推导的方式:对第i个数,前i-1个位置已经产生了(i - 1)!种情况,第i个位置的数字每加1,则总的情况数就会增加(i - 1)!,利用这个性质即可用夹逼法求出每一位的数字是多少。自己的sb做法(17ms):

class Solution {        public static int[] fac = new int[11];        static {        fac[0] = 1;        fac[1] = 1;        for (int i = 2; i <= 10; i ++) {            fac[i] = fac[i - 1] * i;        }    }        public static void remove(int[] num, int pos, int n) {        for (int i = pos; i < n; i ++) {            num[i] = num[i + 1];        }    }    public String getPermutation(int n, int k) {        int[] num = new int[11];        for (int i = 1; i <= 10; i ++) {            num[i] = i;        }        String ans = "";        for (int i = n; i >= 1 && k > 0; i --) {            if (fac[i - 1] >= k) {                ans += (num[1] + "");                remove(num, 1, n);                n --;            } else {                int j = 1;                while (j * fac[i - 1] < k) {                    j ++;                }                ans += (num[j] + "");                k -= (j - 1) * fac[i - 1];                remove(num, j, n);                n --;            }         }        return ans;    }}


后来才知道其实这就是康托展开式(15ms):

class Solution {        public static int[] fac = new int[11];        static {        fac[0] = 1;        fac[1] = 1;        for (int i = 2; i <= 10; i ++) {            fac[i] = fac[i - 1] * i;        }    }    public String getPermutation(int n, int k) {        int[] num = new int[11];        for (int i = 1; i <= 10; i ++) {            num[i] = i - 1;        }        k --;        boolean[] vis = new boolean[n + 1];        Arrays.fill(vis, false);        String ans = "";        int div = 0;        for (int i = n; i >= 1; i --) {            div = k / fac[i - 1];            k %= fac[i - 1];            int j = 1;            for (; j <= n; j ++) {                if (num[j] == div && !vis[j]) {                    ans += (j + "");                    vis[j] = true;                    break;                }            }            for (j ++; j <= n; j ++) {                num[j] --;            }                  }        return ans;    }}


原创粉丝点击