给出集合 [1,2,3,...,n]
,其所有元素共有 n!
种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3
时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n
和 k
,返回第 k
个排列。
思路一:模拟排序返回第k个排序
int getFactorial(int n)
{
int res = 1;
for(int i = 1;i<n+1;i++)
{
res*=i;
}
return res;
}
char * getPermutation(int n, int k){
int i = 0,iNfac = 0,iTmpA = 0,iTmpB = k - 1;
char iTmp = 0;
char *res = (char*)malloc(sizeof(char) * (n + 1));
for (i = 0; i < n; i++)
{
res[i] = i + '1';
}
res[i] = '\0';
for (i = 0; i < n - 1; i++)
{
iNfac = getFactorial(n - 1 - i);
iTmpA = iTmpB / iNfac;
iTmpB = iTmpB % iNfac;
iTmp = res[i + iTmpA];
memcpy(&res[i + 1], &res[i], sizeof(char) * (iTmpA));//移动字符
res[i] = iTmp;
if (0 == iTmpB)
{
break;
}
}
return res;
}
时间复杂度O(n),空间复杂度O(n)
分析:
本题要求第k个排序,可想到先将1到n的字符先放到数组中,再根据所给的k值调换各个数字顺序,最后返回正确答案。每次移动的时候先计算当前位置的阶乘,利用该值除k-1得到所要移动的数的位置,对k-1取余得到还有多少步,最后当0 == iTmpB时返回res
总结:
本题考察对字符串的应用,理解如何排序并编写数字移动的代码即可解决