90. 子集 II【Normal】【回溯】

给你一个整数数组 nums ,其中可能包含重复元素

请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集

返回的解集中,子集可以按 任意顺序 排列。


示例 1:

输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]


示例 2:

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


提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10


思路:

1. 对数组,先排序

2. 回溯

3. 去重


解答:

/**
 * @param {number[]} numArr
 * @return {number[][]}
 */
var subsetsWithDup = function(numArr) {
    // 1.必须先排序
    numArr.sort((a, b) => {
        // 升序
        return a - b;
    })
    
    let res = [];
    let path = [];
    let startIndex = 0;
    
    // 2.回溯
    backtrack(numArr, startIndex, path, res);
    
    // 3.结果数组去重
    let tmp = [];
    let set = new Set();
    for(let path of res){
        if(!set.has(path.toString())){
            set.add(path.toString());
            tmp.push(path);
        }
    }
    return tmp;
};

function backtrack(numArr, startIndex, path, res){
    // 没有递归终点
    res.push([...path]);
    
    // 遍历所有选择
    let len = numArr.length;
    for(let i = startIndex; i < len; i++) {
        let num = numArr[i];
        // 由于有重复的,所以有两种选择:选它或者不选它
        // 1. 而且必须是选它 在前面
        // 作出选择
        path.push(num);
        // 进入下一层
        backtrack(numArr, i + 1, path, res);
        // 撤销选择
        path.pop();
        
        // 2. 然后才是 不选它,并且要跳过后面和它一样的数字
        while(i < len && numArr[i] === num){
            i++;
        }
        // 进入下一层
        backtrack(numArr, i, path, res);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值