题目
Given an integer array nums
that may contain duplicates, return all possible subsets (the power set).
The solution set must not contain duplicate subsets. Return the solution in any order.
Example 1:
Input: nums = [1,2,2]
Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
Example 2:
Input: nums = [0]
Output: [[],[0]]
Constraints:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
思路
中心思想:如果序列中有重复元素,那么可以将重复的元素作为一个整体考虑,如果有元素3出现2次,那么可以将其作为元素(3)、(3, 3)合入序列中。
解法1:使用Counter对象将nums序列变成键为元素、值为出现次数的字典,随后遍历字典,将元素、出现次数考虑在内合入序列中。
解法2:首先排序序列,然后遍历,当遇到后几位是重复元素时,将它们作为整体合入序列中。
解法3:与解法2类似,不过不需要维护额外变量,由于重复元素作为一个整体,如果有元素3出现2次,那么可以得到元素(3)和(3, 3)合入的序列数量都是固定的,也就是确认当前元素是重复元素时,只需要合入第一个重复元素相等数量的子序列。
代码
python版本:
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res = [[]]
cnt = Counter(nums)
for k, v in cnt.items():
res += [r+[k]*c for c in range(1, v+1) for r in res]
return res
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res = [[]]
nums.sort()
i = 0
while i < len(nums):
cnt = 1
while i+cnt < len(nums) and nums[i+cnt] == nums[i]:
cnt += 1
res += [r+[nums[i]]*c for c in range(1, cnt+1) for r in res]
i += cnt
return res
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res = [[]]
nums.sort()
for i in range(len(nums)):
if i == 0 or nums[i-1] != nums[i]:
l = len(res)
res += [r+[nums[i]] for r in res[len(res)-l:]]
return res