力扣90:子集Ⅱ

本题是力扣78的升级版,多了一个限制条件,就是集合里面会出现重复的元素,而且结果集里边不能有重复的子集,就比如集合{1,2,2}当中,返回的结果集可以包含集合{2,2}但是不能有两个{2,2}.因此我们需要考虑额外增加一个数组used,来记录这个元素是否被使用过,还需要用这个集合的元素来反映重复元素的去重情况。我们根据分析情况画出的树形图如下

 我们从这张图中不难发现,我们需要先对集合排序,然后在处理节点。由于也是子集问题,每个节点都需要收集到结果集里边,而且由于是在同一个数组里边求集合,所以同样需要startindex来标识一下下一层递归从哪个元素开始递归。而且我们在这里还要明确一下去重逻辑,排序之后,相同数值大小的元素肯定是挨着的,要是当前遍历元素的前一个元素的used数组的值是false,那就代表着和当前元素num[i]的值相同的num[i-1]已经被使用过了,那么现在就不能用了,我们应该用continue结束这一次的循环,开始进行下一次的循环。

具体的代码如下

void backtrack(vector<int>&num,vector<bool>& used,int startindex)
{
    res.push_back(path);
    if(startindex>=num.size())return ;
    for(int i=startindex,i<num.size();i++)
    {
        if(i>0&&num[i]==num[i-1]&&used[i-1]==false)
            continue;
        
        path.push_back(num[i]);
        num[i]=false;
        backtrack(num,used,i+1);
        used[i]=true;
        path.pop_back();
    }   
}

vector<vector<int>> subsetsWithDup(vector<int>& nums) 
{
        vector<bool>used(nums.size(),false);
        sort(nums.begin(),nums.end());
        backtrack(num,used,0);

        return res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值