第一时间很容易想到回溯,回溯是寻找全集的很好的办法
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res=[]
n=len(nums)
def track_back(i,tmp):
if(i==n):
return
res.append(tmp)
for j in range(i+1,n):
track_back(j,tmp+[nums[j]])
track_back(-1,[])
return res
一种思路,对于 [ 1 , 2 , 3 ] [1,2,3] [1,2,3],
初始化:
r e s = [ ] res=[] res=[]
遇到1:
[ 1 ] [1] [1]
r e s res res: [ [ ] , [ 1 ] ] [[],[1]] [[],[1]]
遇到2:
[ 2 ] [2] [2]
[ 1 , 2 ] [1,2] [1,2]
r e s res res: [ [ ] , [ 1 ] , [ 2 ] , [ 1 , 2 ] ] [[],[1],[2],[1,2]] [[],[1],[2],[1,2]]
遇到3:
[ 3 ] [3] [3]
[ 1 , 3 ] [1,3] [1,3]
[ 2 , 3 ] [2,3] [2,3]
[ 1 , 2 , 3 ] [1,2,3] [1,2,3]
r e s res res: [ [ ] , [ 1 ] , [ 2 ] , [ 1 , 2 ] , [ 3 ] , [ 1 , 3 ] , [ 2 , 3 ] , [ 1 , 2 , 3 ] ] [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
遇到一个数,将结果中的每一个子集数组加上当前元素,形成新的子集,并加入到 r e s res res中。
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res=[[]]
for num in nums:
res=res+[[num]+i for i in res]
return res
对于 [ 1 , 2 , 3 ] [1,2,3] [1,2,3],可用三位二进制表示是否选择对应下标的数组元素。则有 8 8 8种组合方式。
二进制 对应数字 |
1 | 2 | 3 | 对应子集 |
---|---|---|---|---|
0 | 0 | 0 | 0 | [ ] [] [] |
1 | 0 | 0 | 1 | [ 3 ] [3] [3] |
2 | 0 | 1 | 0 | [ 2 ] [2] [2] |
3 | 0 | 1 | 1 | [ 2 , 3 ] [2,3] [2,3] |
4 | 1 | 0 | 0 | [ 1 ] [1] [1] |
5 | 1 | 0 | 1 | [ 1 , 3 ] [1,3] [1,3] |
6 | 0 | 1 | 1 | [ 2 , 3 ] [2,3] [2,3] |
7 | 1 | 1 | 1 | [ 1 , 2 , 3 ] [1,2,3] [1,2,3] |
初始化数组长度 n n n,最终结果的长度 r e s _ l e n = 1 < < n res\_len=1<
对于每种结果,对于 i i i在遍历区间 [ 0 , r e s _ l e n ) [0,res\_len) [0,res_len)中:
返回 r e s res res
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
res_len = 1 << n
res = []
for i in range(res_len):
cur = []
for j in range(n):
if i >> j & 1:
cur.append(nums[j])
res.append(cur)
return res