LeetCode.60. 第k个排列
给出集合 [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)初始数组nums存放1~n的数
2)申请一个字符数组res:从左到右第一位数
1.res[0] = nums[k / (n-1)!] ,
2.移除nums[k / (n-1)!]后面的数字依次向前移动,
3.k %= (n-1)!
从左到右第二位数
1.res[1] = nums[k / (n-2)!] ,
2.移除nums[k / (n-2)!]后面的数字依次向前移动,
3.k %= (n-2)!
......
从左到右第x位数
1.res[x - 1] = nums[k / (n-x-1)!],
2.移除nums[k / (n-x-1)!]后面的数字依次向前移动
3.k %= (n-x-1)!
int factorial(int n)
{
int res = 1;
while (n)
{
res *= n--;
}
return res;
}
void deleteNum(int *arr, int numSize, int n)
{
while (n < numSize - 1)
{
arr[n++] = arr[n + 1];
}
}
char * getPermutation(int n, int k){
int factValue = 0;
char *result = (char *)calloc(n + 1, sizeof(char)); //目标字符数组
int *nums = (int *)malloc(n * sizeof(int));
// int nums[n];
for (int i = 0; i < n; ++i)
{
nums[i] = i + 1;
}
k--;
for (int j = 0; j < n; ++j)
{
factValue = factorial(n - j - 1);
result[j] = nums[k / factValue] + '0'; //+‘0’转换为字符
deleteNum(nums, n - j, k / factValue); //删除这个数nums[k / factValue]
k %= factValue;
}
free(nums);
return result;
}