學渣帶你刷Leetcode0047全排列 II

題目描述

給定一個可包含重複數字的序列,返回所有不重複的全排列。

示例:

輸入: [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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章