56.子集

4 阅读1分钟

题目链接

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

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

解法1 dfs回溯

思路

每次进来直接将路径先放在结果集里,然后再去根据 index 来递归后面的数字。

为什么要根据 index 呢?因为要保证结果去重,数组里每个数不一样,根据 index 就可以定位到当前枚举的是哪个数。

在每次选择一个数字时更新 path,并且要在回溯时撤销选择。

代码

function subsets(nums: number[]): number[][] {
    const result = [];

    const dfs = (path, index) => {
        result.push([...path]);

        for (let i = index; i < nums.length; i++) {
            path.push(nums[i]);
            dfs(path, i + 1);
            path.pop();
        }
    };

    dfs([], 0);
    return result;
};

时空复杂度

时间复杂度:存在选和不选两个操作,一共 n 个数,所以是 O(2^n)

空间复杂度:O(n + 2^n)n 是递归栈空间

解法2 迭代法

思路

对于每一个数字,遍历当前所有的子集,把当前数字加到这些子集上,生成新的子集,并加入到 result 中。

代码

function subsets(nums: number[]): number[][] {
    let result: number[][] = [[]];

    for (let num of nums) {
        let newSubsets = [];
        for (let subset of result) {
            // 将当前数字加到已有子集上,形成新的子集
            newSubsets.push([...subset, num]);
        }
        result = result.concat(newSubsets);
    }

    return result;
};

时空复杂度

时间复杂度:O(2^n)

空间复杂度:O(2^n)