給定一組不含重複元素的整數數組 nums,返回該數組全部可能的子集(冪集)。數組
說明:解集不能包含重複的子集。ui
示例:spa
輸入: nums = [1,2,3]
輸出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
複製代碼
使用位移和按位與的思路,來自leetcode的評論區。這個思路相對來講比較抽象,下面是具體的解釋。code
舉一個例子🌰,nums = [a, b, c]
, 若是數組中全部的子項全都存在,咱們能夠將其抽象成一個二進制數,111
(1表明數字存在)leetcode
子集 | 二進制數 |
---|---|
[] | 000 |
[a] | 100 |
[b,c] | 110 |
[a,c] | 101 |
[a,b,c] | 111 |
[b] | 010 |
[b,c] | 011 |
[c] | 001 |
111
的十進制數表示是7, 000
的十進制數表示是0,咱們只須要遍歷從0到7的十進制數便可獲得全部的子集。string
如何將二進制數,反序列化爲集合呢?咱們能夠利用按位與&操做符。io
舉一個例子🌰。例如:110
表示[a,b]
, 咱們使用,110 & 100
等於1,表示a
存在。110 & 010
等於1,表示b
存在。110 & 001
等於0,表示c
不存在。table
子集 | A | B | C |
---|---|---|---|
[] | 000 & 100 === 0 | 000 & 010 === 0 | 000 & 001 === 0 |
[a] | 100 & 100 === 1 | 100 & 010 === 0 | 100 & 001 === 0 |
[b,c] | 110 & 100 === 1 | 110 & 010 === 1 | 110 & 001 === 0 |
…… | …… | …… |
假設參數數組的長度爲4。咱們該怎麼獲取子集的數量呢?咱們由上面👆的思路可知,若是數組長度爲4,那麼集合的數量就爲0b1111
。function
/** * @param {number[]} nums * @return {number[][]} */
var subsets = function(nums) {
// 子集的數量
let len = ''
const result = [[]]
for (let i = 0; i < nums.length; i++) {
len += '1'
}
// 獲取最大的子集數量,[1, 2, 3]最大子集數量`111`
len = parseInt(len, 2)
for (let i = 1; i <= len; i++) {
let temp = []
// 1 << 0 `0b001`
// 1 << 1 `0b010`
// 1 << 2 `0b100`
// 判斷每個位置是否存在
for (let j = 0; j < nums.length; j++) {
if (i & (1 << j)) {
temp.push(nums[j])
}
}
result.push(temp)
}
return result
};
複製代碼
/** * @param {number[]} nums * @return {number[][]} */
var subsets = function(nums) {
let result = []
for (let i = 0; i < nums.length; i++) {
let temp = []
for (let j = 0; j < result.length; j++) {
temp.push([...result[j], nums[i]])
}
result = [...result, ...temp, [nums[i]]]
}
result = [...result, []]
return result
};
複製代碼