学渣带你刷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;
}

 

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