回溯算法子集

回溯算法
子集问题
区别 不在终止条件完成记录进res 每个节点都要 费根节点
*path 单个结果
**res 结果
bt(char *s,startindex)
{
//进入
res++

//全集先放再结束
//可以不要if(startindex>=s.len) return
for(i=startindex;i<s.len;i++)//这边也有终止
{
path.push

    bt(s,i+1)
    回退

}
return

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

 

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:

输入:nums = [0]
输出:[[],[0]]
 

提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/**
 * 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().
 */


void backtracking(int *nums,int numsize,int **res, int *returnSize,int* path,int pathsize,int startIndex,int **returnColumnSizes)
{
    int i;
    //子集问题 path的每一次记录即递归一次得到一个节点就记录
    res[*returnSize] =(int *) malloc(sizeof(int)*pathsize);//int *
    memcpy(res[*returnSize],path,sizeof(int)*pathsize);//%%%%%
    //记录长度==pathsize
    (*returnColumnSizes)[*returnSize] = pathsize;
    (*returnSize)++;
    //
    if(startIndex>=numsize) return;
    for(i=startIndex;i<numsize;i++)
    {
        
        path[pathsize]=nums[i];
        backtracking(nums,numsize,res,returnSize,path,pathsize+1,i+1,returnColumnSizes);
    }
    return;

}
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){

    int **res =(int **) malloc(sizeof (int*)*2000);
    int *path =(int *)  malloc(sizeof(int )*20);
    *returnColumnSizes =(int *) malloc(sizeof (int)*2000);//为何int **不可以?
    *returnSize =0;

    backtracking(nums,numsSize,res,returnSize,path,0,0,returnColumnSizes);
    return res;
}

有重复元素的求子集

/**
 * 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 used[11]={0};

 int cmp(const void* a1, const void* a2) {
    return *((int*)a1) - *((int*)a2);
}

void backtrack(int *nums,int numsSize, int **res,int* returnSize,int *path,int pathSize ,int** returnColumnSizes,int startIndex,int* used)
{
    int i;
    res[*returnSize] = (int *) malloc (sizeof(int)*pathSize);
    memcpy(res[*returnSize],path,sizeof(int)*pathSize);
    (*returnColumnSizes)[(*returnSize)++] =pathSize;

    if(startIndex>=numsSize) return;

    for(i=startIndex;i<numsSize;i++)
    {
        if(i>0 && used[i-1]==0&&nums[i]== nums[i-1]) continue;//不是break 跳过####
            path[pathSize]=nums[i];
            used[i]=1;
            backtrack(nums,numsSize, res,returnSize,path,pathSize+1 ,returnColumnSizes,i+1, used);
            used[i]=0;
    }
    return;
}

int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){

    int **res =(int **) malloc(sizeof (int*)*2000);
    int *path =(int *)  malloc(sizeof(int )*20);
    *returnColumnSizes =(int *) malloc(sizeof (int)*2000);//为何int **不可以?
    *returnSize =0;

    qsort(nums,numsSize,sizeof(int),cmp);


     backtrack(nums,numsSize, res,returnSize,path,0 ,returnColumnSizes,0, used);
    return res;



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值