/*
给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n 和 k,返回第 k 个排列。
示例 1:
输入:n = 3, k = 3
输出:"213"
示例 2:
输入:n = 4, k = 9
输出:"2314"
示例 3:
输入:n = 3, k = 1
输出:"123"
提示:
1 <= n <= 9
1 <= k <= n!
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/permutation-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
char * getPermutation(int n, int k)
{
int *nums = (int *)malloc(n * sizeof(int));
bool *flags = (bool *)malloc(n * sizeof(bool));
char *out = (char *)malloc((n + 1) * sizeof(char));
int i, j, len = 0;
memset(flags, false, n * sizeof(bool));
nums[0] = 1;
for (i = 1; i < n; i++) {
nums[i] = nums[i-1] * (i + 1);
}
assert(k <= nums[n-1]);
//search
i = n - 2;
while ((i >= 0) && (k > 0)) {
int m = k / nums[i];
k = k % nums[i];
int a = m + ((k > 0) ? 1 : 0);
int count = 0;
for (j = 0; j < n; j++) {
if (!flags[j]) {
count++;
}
if (count >= a) {
break;
}
}
flags[j] = true;
out[len++] = j + 1 + '0';
i--;
}
for (i = n-1; i >= 0; i--) {
if (!flags[i]) {
out[len++] = i + 1 + '0';
}
}
free(flags);
free(nums);
out[len] = '\0';
return out;
}
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("please input permutation n and k!\n");
return 0;
}
int n = atoi(argv[1]);
int k = atoi(argv[2]);
char *ret = getPermutation(n, k);
printf("permutation n/k: %s\n", ret);
free(ret);
return 0;
}
排列序列
最新推荐文章于 2024-08-16 21:41:25 发布