给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations-ii
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#define SIZE 10000
int comp(const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
void backtrack(int selectId, int numsSize, int* nums, int *used, int* list, int* returnSize, int** returnColumnSizes, int** ret)
{
if (selectId == numsSize) {
(*returnColumnSizes)[*returnSize] = numsSize;
memcpy(ret[*returnSize], list, sizeof(int) * numsSize);
(*returnSize)++;
ret[*returnSize] = (int *)calloc(numsSize, sizeof(int));
return;
}
for (int j = 0; j < numsSize; j++) {
if (used[j] == 1) {
continue;
}
used[j] = 1;
list[selectId] = nums[j];
backtrack(selectId + 1, numsSize, nums, used, list, returnSize, returnColumnSizes, ret);
//从backtrack退出两种情况:
// 1.全排列完成,最后一个数字出列;
// 2.该数字已经选过了,选后面的数字
used[j] = 0;
while (j < numsSize - 1 && nums[j] == nums[j + 1]) {
j++;
}
}
}
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
{
if (nums == NULL || numsSize == 0 || returnSize == NULL || returnColumnSizes == NULL) {
return NULL;
}
qsort(nums, numsSize, sizeof(int), comp);
int **ret = (int **)malloc(SIZE * sizeof(int *));
ret[0] = (int *)calloc(numsSize, sizeof(int));
*returnColumnSizes = (int *)calloc(SIZE, sizeof(int));
*returnSize = 0;
int* list = (int *)calloc(numsSize, sizeof(int));
int* used = (int *)calloc(numsSize, sizeof(int));
backtrack(0, numsSize, nums, used, list,returnSize, returnColumnSizes, ret);
free(list);
free(used);
return ret;
}
void testcase1(void)
{
int nums[3] = {1, 2, 3};
int numsSize = 3;
int returnSize;
int* returnColumnSizes;
int **ret = permuteUnique(nums, numsSize, &returnSize, &returnColumnSizes);
for (int i = 0; i < returnSize; i++) {
for (int j = 0; j < returnColumnSizes[i]; j++) {
printf("%d ", ret[i][j]);
}
printf("\n ");
}
printf("********************************************\n ");
}
void testcase2(void)
{
int nums[3] = { 1, 1, 2 };
int numsSize = 3;
int returnSize;
int* returnColumnSizes;
int **ret = permuteUnique(nums, numsSize, &returnSize, &returnColumnSizes);
for (int i = 0; i < returnSize; i++) {
for (int j = 0; j < returnColumnSizes[i]; j++) {
printf("%d ", ret[i][j]);
}
printf("\n ");
}
printf("********************************************\n ");
}
int main()
{
testcase1();
testcase2();
return 0;
}