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; } };