46. 全排列¶
难度:中等
题目¶
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
题解¶
使用回溯算法,对于给定的序列:
- 若长度为1,则只有一种排列方式,直接返回
- 若长度大于1,则可以:
- 将序列中第一个数放在排列的第一位,然后与后面部分的全排列合并
- 将序列中第二个数放在排列的第一位,然后与后面部分的全排列合并
- ……
- 将序列中最后一个数放在排列的第一位,然后与后面部分的全排列合并
- 最终结果包含如上所有的排列。
对于长度为\(n\)的序列,共有\(n!\)种排列。
int fact(int x)
{
if (!x)
return 0;
int i = 1, ret = 1;
for (i = 1; i <= x; i++)
ret *= i;
return ret;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
if (numsSize < 2)
{
*returnSize = 1;
*returnColumnSizes = (int *)malloc(sizeof(int) * *returnSize);
*returnColumnSizes[0] = numsSize;
if (numsSize == 0)
return NULL;
int **ret = (int **)malloc(sizeof(int *) * *returnSize);
*ret = (int *)malloc(sizeof(int));
**ret = *nums;
return ret;
}
*returnSize = fact(numsSize);
*returnColumnSizes = (int *)malloc(sizeof(int *) * *returnSize);
int *sub = (int *)malloc(sizeof(int) * numsSize), i = 0, **rec = NULL, recSize, *recColSize,
**ret = (int **)malloc(sizeof(int *) * *returnSize), retpos = 0, j = 0;
for (i = 0; i < *returnSize; i++)
(*returnColumnSizes)[i] = numsSize;
for (i = 0; i < numsSize; i++)
{
sub = memcpy(sub, nums, sizeof(int) * numsSize);
swap(sub + i, sub);
rec = permute(sub + 1, numsSize - 1, &recSize, &recColSize);
for (j = 0; j < recSize; j++)
{
ret[retpos] = (int *)malloc(sizeof(int) * numsSize);
ret[retpos][0] = sub[0];
memcpy(ret[retpos] + 1, rec[j], sizeof(int) * (numsSize - 1));
retpos++;
}
}
return ret;
}