60.Permutation Sequence

给定一个正整数 n ,从 1 ~ n 的数全排列,共有 n! 种排列方法,求出其中的第 k 个排列。

Input: n = 3, k = 3
Output: "213"


思路:
这题跟 46 很像,一开始也采用 46题的方法,但是输出来的顺序不对。

错误的解法:

class Solution {
public:
    string getPermutation(int n, int k) {
        string res = "";
        vector<int> nums;
        for (int i = 1; i <= n; i++) nums.push_back(i);
        int count = 0;
        getPermutationDFS(nums, 0, res, count, k);
        return res;
    }

    void getPermutationDFS(vector<int>& nums, int start, string& res, int& count, int k) {
        if (start == nums.size()) {
            count += 1;
            if (count == k) {
                for (auto n : nums) res += to_string(n); return;
            }
            if (count > k) return;
        }
        for (int i = start; i < nums.size(); i++) {
            swap(nums[i], nums[start]);
            getPermutationDFS(nums, start + 1, res, count, k);
            swap(nums[i], nums[start]);
        }
    }
};

 

二、正确的解法,见Grandyang

 解题思想是找规律,对于整数 n ,则其高位 1/2,……,每一位后面都有 n-1个数字,而这 n-1 个数字有 (n-1)! 种排列方法,所以 k/(n-1)! 就可以定位到最高位是多少,再对取模 k = k%(n-1)! ,继续循环,知道找出最终解。

class Solution {
public:
    string getPermutation(int n, int k) {
        string res = "", s = "123456789";
        int *a = new int[n];
        a[0] = 1;
        for (int i = 1; i < n; i++) a[i] = i * a[i - 1];
        k -= 1;
        for (int i = n-1; i >=0; i--) {
            int num = k / a[i];
            res += s[num];
            s.erase(num, 1);
            k = k % a[i];
        }
        delete []a;
        return res;
    }
};

 

posted @ 2020-05-30 22:36  星海寻梦233  阅读(126)  评论(0编辑  收藏  举报