目录
- 题目描述
- 解法
- 方法一:DFS(回溯)
- 方法二:二进制枚举
- 运行结果
- 方法一
- 方法二
题目描述
给你一个整数数组 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] <= 10
- nums 中的所有元素 互不相同
解法
方法一:DFS(回溯)
我们设计一个函数 dfs(i),表示从数组的第 i 个元素开始搜索所有子集。函数 dfs(i) 的执行逻辑如下:
- 如果 i=n,表示当前已经搜索结束,将当前得到的子集 t 加入答案数组 ans 中,然后返回;
- 否则,我们可以选择不选择当前元素,直接执行 dfs(i+1);也可以选择当前元素,即把当前元素 nums[i] 加入子集 t,然后执行 dfs(i+1),注意要在执行 dfs(i+1) 以后再将 nums[i] 从子集 t 中移除(回溯)。
在主函数中,我们调用 dfs(0),即从数组的第一个元素开始搜索所有子集。最后返回答案数组 ans 即可。
时间复杂度 O(n×2 n ),空间复杂度 O(n)。其中 n 为数组的长度。一共有 2 n 个子集,每个子集需要 O(n) 的时间来构造。
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def dfs(i):
if i == len(nums):
ans.append(t[:])
return
dfs(i + 1)
t.append(nums[i])
dfs(i + 1)
t.pop()
ans = []
t = []
dfs(0)
return ans
方法二:二进制枚举
我们也可以使用二进制枚举的方法得到所有的子集。
我们可以使用 2 n 个二进制数来表示 n 个元素的所有子集,对于当前二进制数 mask,如果第 i 位为 1,表示选择了第 i 个元素,否则表示不选择第 i 个元素。
时间复杂度 O(n×2 n ),空间复杂度 O(n)。其中 n 为数组的长度。一共有 2 n 个子集,每个子集需要 O(n) 的时间来构造。
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
ans = []
for mask in range(1 << len(nums)):
t = [x for i, x in enumerate(nums) if mask >> i & 1]
ans.append(t)
return ans