给你一个整数数组
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)