78. 子集

一、题目描述

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

二、解题思路 & 代码

2.1 迭代

class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = [[]]
for i in nums:
res = res + [[i] + num for num in res]
return

复杂度分析

  1. 时间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python,生成所有子集,并复制到输出结果中。
  2. 空间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python,这是子集的数量。

对于给定的任意元素,它在子集中有两种情况,存在或者不存在(对应二进制中的 0 和 1)。因此,N 个数字共有 【LeetCode】78. 子集 & 90. 子集 II_数据结构_03

2.2 递归(回溯)

class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = []
n = len(nums)

def helper(i, tmp):
res.append(tmp)
for j in range(i, n):
helper(j + 1,tmp + [nums[j]] )
helper(0, [])
return

复杂度分析

  1. 时间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python,生成所有子集,并复制到输出集合中。
  2. 空间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python,存储所有子集,共 N 个元素,每个元素都有可能存在或者不存在。

2.3 字典排序(二进制排序) 子集

参考:
​​​LeetCode官方题解​

class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
output = []

for i in range(2**n, 2**(n + 1)):
# generate bitmask, from 0..00 to 1..11
bitmask = bin(i)[3:]

# append subset corresponding to that bitmask
output.append([nums[j] for j in range(n) if bitmask[j] == '1'])

return

复杂度分析

  1. 时间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python
  2. 空间复杂度:【LeetCode】78. 子集 & 90. 子集 II_python

参考:

  1. ​LeetCode官方题解​
  2. ​LeetCode题解​

==================================================

90. 子集 II

一、题目描述

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]

二、解题思路 & 代码

2.1 递归

直接根据 78 题 的思路去做的,这个比较好改,我们只需要判断当前数字和上一个数字是否相同,相同的话跳过即可。当然,要把数字首先进行排序。

class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res = []
n = len(nums)
nums.sort()
def helper(idx, tmp):
res.append(tmp)
for i in range(idx, n):
if i > idx and nums[i] == nums[i-1]:
continue
helper(i+1, tmp + [nums[i]])
helper(0, [])
return

2.2 迭代

class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
if not nums: return []
nums.sort()
res = [[]]
cur = []
for i in range(len(nums)):
if i > 0 and nums[i - 1] == nums[i]:
cur = [tmp + [nums[i]] for tmp in cur]
else:
cur = [tmp + [nums[i]] for tmp in res]
res += cur
return