90.子集II
backtracking, https://leetcode.cn/problems/subsets-ii/
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的 子集(幂集)。
数组的子集是数组中选择一些元素(可能为空)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]示例 2:
输入:nums = [0]
输出:[[],[0]]提示:
1 <= nums.length <= 10-10 <= nums[i] <= 10
python
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()
ans = set()
def dfs(i, path):
if i == n:
ans.add(tuple(path))
return
dfs(i+1, path + [nums[i]])
dfs(i+1, path)
dfs(0, [])
return list(ans)考虑数组 [1,2,2],选择前两个数,或者第一、三个数,都会得到相同的子集。
也就是说,对于当前选择的数 x,若前面有与其相同的数 y,且没有选择 y,此时包含 x 的子集,必然会出现在包含 y 的所有子集中。可以通过判断这种情况,来避免生成重复的子集。
python
from typing import List
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
nums.sort() # 对输入数组进行排序
result = []
def backtrack(start=0, current=[]):
# 将当前构建的子集添加到结果集中
result.append(current[:])
for i in range(start, len(nums)):
# 如果当前元素与前一个元素相同,则跳过,避免重复子集
# i > start 确保只跳过当前层的重复元素,而不会影响递归中更深层的重复元素
if i > start and nums[i] == nums[i-1]:
continue
# 做选择
current.append(nums[i])
# 递归调用,继续构建子集
backtrack(i + 1, current)
# 撤销选择
current.pop()
backtrack()
return result