给出集合 [1,2,3,…,n]
,其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n 和 k,返回第 k 个排列。
说明:
- 给定 n 的范围是 [1, 9]。
- 给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3 输出: "213"
示例 2:
输入: n = 4, k = 9 输出: "2314"
对于全排列的题目前看到三道,1、全排列;2、下一个排列;3、第k个排列;
三道题的解题方法一致,就是输出的结果不同而已,要想找下一个排列经过三个步骤:1、从后往前找最大的值并记录索引值index;2、从后往前找比index-1对应值最大且最小的值并交换;3、将包含index之后的值从小到大排序;
这道题要找第k个,那么就用一个变量计数就行流;返回值是字符串,自己再做进一步处理;细节见代码:
class Solution {
public:
void swap_sort(vector<int> &nums, int start, int end)
{
while (start < end)
{
int tmp = nums[start];
nums[start++] = nums[end];
nums[end--] = tmp;
}
}
string getPermutation(int n, int k) {
vector<int> nums;
for (int j = 1; j <= n; j++)
{
nums.push_back(j);
}
int i = 1;
while (i < k)
{
int right = nums.size() - 1;
//后找
while (right > 0 && nums[right] <= nums[right - 1])
{
right--;
}
//小大
int right_new = nums.size() - 1;
while (right_new >= right)
{
if (nums[right_new] < nums[right - 1])
{
right_new--;
}
else
{
break;
}
}
//交换
int temp = nums[right - 1];
nums[right - 1] = nums[right_new];
nums[right_new] = temp;
//排序
swap_sort(nums, right, nums.size() - 1);
i++;
}
string result = "";
for (int j = 0; j < nums.size(); j++)
{
result += (nums[j] + '0');
}
return result;
}
};
加油吧各位,这是面试常考题;