题目:[1]
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明: 解集不能包含重复的子集。
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
抛砖引玉
使用过递归回溯算法解决过:
一句话递归回溯算法的逻辑简要概况就是:
在选择多个原数组的元素组成新成组合时,对于任何一个原数组的元素在新的组合中都可以对其有两种选择形式:当前位置选择或者不选择。
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsets = function(nums) {
let _result = []
if (nums.length === 0) _result
function helper(index, item) {
if (index === nums.length) {
_result.push([...item])
return
}
item.push(nums[index])
helper(index + 1, item)
// 回溯
item.pop()
helper(index + 1, item)
}
helper(0, [])
return _result
}
从上面的逻辑可以知道,在组成子集时对原数组的元素有选择和不选择两种方式,那么用 0 代码不选择,1 代表选择,那么就可以借助二进制的为元素来枚举子集。
nums = [1,2,3]
二进制 | 子集 | 十进制 |
---|---|---|
000 | [] | 0 |
001 | [3] | 1 |
010 | [2] | 2 |
011 | [2,3] | 3 |
100 | [1] | 4 |
101 | [1,3] | 5 |
110 | [1,2] | 6 |
111 | [1,2,3] | 7 |
var subsets = function(nums) {
let _result = [],
len = nums.length
for (let i = 0; i < 1 << len; ++i) {
let item = []
for (let j = 0; j < len; ++j) {
if (i & (1 << j)) {
item.push(nums[j])
}
}
_result.push(item)
}
return _result
}