「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」。
题目
链接:leetcode-cn.com/problems/su…
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
**输入:**nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
**输入:**nums = [0] 输出:[[],[0]]
提示:
1 <= nums.length <= 10-10 <= nums[i] <= 10nums中的所有元素 互不相同
解题思路
- 迭代
依次把每个元素插入到之前的集合中生成新的结果集合
- 时间复杂度: O(n*2^n)
- 空间复杂度: O(n*2^n)
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function (nums) {
const res = [[]];
for (let i = 0; i < nums.length; i++) {
const t = [];
for (let j = 0; j < res.length; j++) {
t.push([...res[j], nums[i]]);
}
res.push(...t);
}
return res;
};
- 回溯
每个元素都有两个状态,递归分别尝试两种状态的结果。所以时间复杂度是 O(2^n)
- 时间复杂度: O(2^n)
- 空间复杂度: O(n * 2^n)
var subsets = function (nums) {
const res = [[]];
const divide = (arr, index) => {
if (index >= nums.length) {
return;
}
const t = [...arr, nums[index]];
res.push(t);
divide(t, index + 1);
divide(arr, index + 1);
};
divide([], 0);
return res;
};
- 位运算
每个数字都有两种状态,和二进制是保持一致的,所以有 2^n 个解,把每个数字都转换成二进制。再根据二进制每位上的 1 来表示存在。
额外计算了二进制,效率会比其他方法差一些
- 时间复杂度: O(n * 2^n)
- 空间复杂度: O(n * 2^n)
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function (nums) {
const res = [];
for (let i = Math.pow(2, nums.length) - 1; i >= 0; i--) {
const str = i.toString(2);
const t = [];
for (let j = 0; j < str.length; j++) {
if (str.charAt(j) === "1") {
t.push(nums[j + (nums.length - str.length)]);
}
}
res.push(t);
}
return res;
};
- 其他 这里相比之前几道类似的题,res处不用条件 因为题意是,所有可能的子集,连 [ ] 都不放过 且当前自增变量不能传递下去,要传递下一个自增变量 i + 1 因为并没有说可以重复利用原数组的单个元素去组合子集,所以下一次搜索要从 i + 1 开始,跳过当前元素
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function(nums) {
let n = nums.length;
let tmpPath = [];
let res = [];
let backtrack = (tmpPath,start) => {
res.push(tmpPath);
for(let i = start;i < n;i++){
tmpPath.push(nums[i]);
backtrack(tmpPath.slice(),i+1);
tmpPath.pop();
}
}
backtrack(tmpPath,0);
return res;
};
或
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function(nums) {
var result = [];
var subsets = [];
var index = 0;
var len = nums.length;
function combinate(subsets,index){
// terminator
if(index == len){
result.push(subsets)
return;
}
// process
combinate(subsets,index+1);
subsets.push(nums[index]);
combinate(subsets.slice(0),index+1);
// reverse states
subsets.pop();
//或
// process
// combinate(subsets.slice(0),index+1);
// subsets.push(nums[index]);
// combinate(subsets.slice(0),index+1);
}
combinate(subsets,0);
return result;
};