學渣帶你刷Leetcode0090子集 II

題目描述

給定一個可能包含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

示例:

輸入: [1,2,2]
輸出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/subsets-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().
 */

//方法一:遞歸法

//函數一:快排比較函數
int compare(const void* a, const void* b){
    return *((int*)a) - *((int*)b);
}

//函數二:遞歸法求子集
//1,結束條件 numsSize==0 爲 []
//2,遞歸邏輯 if(nums[n]!=nums[n-1]) f(n)=f(n-1) + (f(n-1)每個元素增加n)
//3,if(nums[n]==nums[n-1]) f(n)=f(n-1)+(f(n-1)所新增元素再增加n)
int recusiveSubset(int* nums, int** pRet, int* pColSize, int*pRetSize, int numsSize){
    int     i           = 0;
    int     iTmpNum     = 0;
    int     iTmpSize    = 0;

    //1,結束條件
    if(numsSize == 0)
    {
        pRet[*pRetSize] = (int*)malloc(sizeof(int) * 0);
        pColSize[*pRetSize] = 0;
        (*pRetSize) += 1;
        iTmpNum = 1;
        return iTmpNum;
    }

    //2,遞歸調用
    iTmpNum = recusiveSubset(nums, pRet, pColSize, pRetSize, numsSize - 1);

    //3,在 f(n-1) 的基礎上得到 f(n)
    if((numsSize > 1) && (nums[numsSize - 1] == nums[numsSize - 2]))
    {
        iTmpSize = *pRetSize;
        //重複元素處理
        for(i = (iTmpSize - iTmpNum); i < iTmpSize; i++)
        {
            pRet[*pRetSize] = (int*)malloc(sizeof(int) * (pColSize[i] + 1));
            memcpy(pRet[*pRetSize], pRet[i], sizeof(int) * pColSize[i]);
            pRet[*pRetSize][pColSize[i]] = nums[numsSize - 1];
            pColSize[*pRetSize] = pColSize[i] + 1;
            *pRetSize += 1;
        }
    }
    else
    {
        iTmpSize = *pRetSize;
        //非重複元素處理
        for(i = 0; i < iTmpSize; i++)
        {
            pRet[*pRetSize] = (int*)malloc(sizeof(int) * (pColSize[i] + 1));
            memcpy(pRet[*pRetSize], pRet[i], sizeof(int) * pColSize[i]);
            pRet[*pRetSize][pColSize[i]] = nums[numsSize - 1];
            pColSize[*pRetSize] = pColSize[i] + 1;
            *pRetSize += 1;
        }

        iTmpNum = iTmpSize;
    }
    return iTmpNum;
}

int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int         iMax        = 2000;
    int         iRetSize    = 0;
    int**       pRet        = NULL;
    int*        pColSize    = NULL;

    //1,初始化
    pRet = (int**)malloc(sizeof(int*) * iMax);
    memset(pRet, 0x00, sizeof(int*) * iMax);
    pColSize = (int*)malloc(sizeof(int) * iMax);
    memset(pColSize, 0x00, sizeof(int) * iMax);

    //1,快速排序包含充足元素的整數數組
    qsort(nums, numsSize, sizeof(int), compare);

    //2,遞歸處理
    recusiveSubset(nums, pRet, pColSize, &iRetSize, numsSize);

    //3,返回
    *returnSize = iRetSize;
    *returnColumnSizes = pColSize;
    return pRet;
}

 

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