題目描述
給定一個可能包含重複元素的整數數組 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;
}