Skip to content
On this page

子集

Question

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

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

思路

如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!

其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。

那么既然是无序,取过的元素不会重复取,写回溯算法的时候,for就要从startIndex开始,而不是从0开始!

有同学问了,什么时候for可以从0开始呢?

排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合。

以示例中nums = [1,2,3]为例把求子集抽象为树型结构,如下:

从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合

之前我们收集的是叶子结点,所以每次都在终止条件中收集

但是在子集问题中,我们收集的是每一个节点,所以不需要再在终止条件中收集,而本题不需要终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了

js
var subsets = function(nums) {
    const res = []  // 结果[][]
    const path = [] // 每次递归的结果[]
    res.push([])
    // startIndex :每次递归的起使位置
    const backtracking = (startIndex)=>{
        for(let i=startIndex;i<nums.length;i++){	// 本层集合中元素
            path.push(nums[i])				// 处理节点
            res.push([...path])
            backtracking(i+1)		// 递归
            path.pop()					//回溯
        }
        console.log(res,path)
    }
    backtracking(0)
    return res
};