题目描述
给定一个可能包含重复元素的整数数组 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;
}