90. 子集 II 回溯+去重

在这里插入图片描述

解题思路

这题和78.子集不一样的地方在于:子集不能重复。我们需要先对集合进行排序,测试用例中其它样例不是按顺序排列的。

依然是回溯三部曲。子集也是组合问题,这次要求同一层上不可以选取相同的元素。

  1. 递归函数的参数:需要用到startIndex,因为在同一个集合里面,来记录搜索的起始位置;
  2. 终止条件:搜索的起始位置>=数组长度;
  3. 单层逻辑:从startIndex开始搜索nums。递归时i+1,因为这题不可以重复选取数组中的元素。 在里面做一个判断,如果i>startIndex && nums[i] ==nums[i-1],就代表同一层中已经选取过了相同元素,continue跳出本次循环。

要注意的是copy()函数必须放在最前面,不然会漏掉集合为空的情况。

int *path;
int pathTop;
int **result;
int resultTop;
int *length;

//从小到大排序
int cmp(const void* a1, const void* a2) {
    return *((int*)a1) - *((int*)a2);
}

void copy(){
    int *temp = malloc(sizeof(int) *pathTop);
    for(int i=0;i<pathTop;i++){
        temp[i] = path[i];
    }
    result[resultTop] = temp;
    length[resultTop++] = pathTop; 
}

void backTrack(int *nums,int numsSize,int startIndex){
    copy();
    if(startIndex >=numsSize){
        return;
    }
    for(int i=startIndex;i<numsSize;i++){
        if(i>startIndex && nums[i]==nums[i-1]){
            continue;
        }else{
            path[pathTop++] = nums[i];
            backTrack(nums,numsSize,i+1);
            pathTop--;
        }
    }
}

int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    path = malloc(sizeof(int) *numsSize);
    result = malloc(sizeof(int*) *2000);
    length = malloc(sizeof(int) *2000);
    pathTop = resultTop = 0;
    qsort(nums,numsSize,sizeof(int),cmp);
    backTrack(nums,numsSize,0);
    *returnSize = resultTop;
    *returnColumnSizes = malloc(sizeof(int) *resultTop);
    for(int i =0;i<resultTop;i++)
        (*returnColumnSizes)[i] = length[i];
    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值