題目描述
給定一個可包含重複數字的序列,返回所有不重複的全排列。
示例:
輸入: [1,1,2]
輸出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/permutations-ii
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
白話題目:
算法:
詳細解釋關注 B站 【C語言全代碼】學渣帶你刷Leetcode 不走丟 https://www.bilibili.com/video/BV1C7411y7gB
C語言完全代碼
/**
* 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().
*/
//方法一:回溯法
//1,以選取的字符數 iCurPos 爲索引,進行回溯
//2,下一層選取數字的規則,只能選取剩下沒有使用過的數字
//3,結束條件,數字填完了
//函數一:計算序列結果大小
int calPermuteSize(int numsSize){
int i = 0;
int iRetSize = 1;
for (i = 1; i <= numsSize; i++)
{
iRetSize *= i;
}
return iRetSize;
}
//函數三:判斷是否是重複元素
bool checkRepeat(int** pRet, int* pRetPos, int iCurPos, int num){
int i = 0;
bool bRet = false;
for (i = 0; i < *pRetPos; i++)
{
if ((0 == memcmp(&pRet[i][0], &pRet[*pRetPos][0], sizeof(int) * iCurPos)) &&
(pRet[i][iCurPos] == num))
{
bRet = true;
break;
}
}
return bRet;
}
//函數二:回溯函數
void backTrackPermute(int* nums, int numsSize, int** pRet, int* pUsed, int* pRetPos, int iCurPos){
int i = 0;
int iTmp = 0;
//1,結束條件
if (iCurPos == numsSize)
{
*pRetPos += 1;
memcpy(pRet[*pRetPos], pRet[(*pRetPos) - 1], sizeof(int) * numsSize); //進行下一個結果的填寫,將當前結果拷貝,否則前面的值爲0
return;
}
//2,回溯處理
for (i = 0; i < numsSize; i++)
{
if (0 == pUsed[i])
{
//4,檢查是否重複,避免除重
if (checkRepeat(pRet, pRetPos, iCurPos, nums[i])) continue;
iTmp = i;
pRet[*pRetPos][iCurPos] = nums[i];
pUsed[i] = 1;
backTrackPermute(nums, numsSize, pRet, pUsed, pRetPos, iCurPos + 1);
//3,回退處理
pUsed[iTmp] = 0;
}
}
return;
}
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int i = 0;
int iRetSize = 0;
int** pRet = NULL;
int* pRetCol = NULL;
int* pUsed = NULL;
int iRetPos = 0;
//1,計算結果數量
iRetSize = calPermuteSize(numsSize);
//2,申請空間
pRet = (int**)malloc(sizeof(int*) * (iRetSize + 1));
pRetCol = (int*)malloc(sizeof(int) * (iRetSize + 1));
pUsed = (int*)malloc(sizeof(int) * numsSize);
memset(pUsed, 0x00, sizeof(int) * numsSize);
for (i = 0; i <= iRetSize; i++)
{
pRet[i] = (int*)malloc(sizeof(int) * numsSize);
memset(pRet[i], 0x00, sizeof(int) * numsSize);
pRetCol[i] = numsSize;
}
//3,調用回溯函數
backTrackPermute(nums, numsSize, pRet, pUsed, &iRetPos, 0);
//4,釋放空間
free(pUsed);
for (i = iRetPos; i <= iRetSize; i++)
{
free(pRet[i]);
}
//5,返回
*returnSize = iRetPos;
*returnColumnSizes = pRetCol;
return pRet;
}