题目:
方法一
对应于Leetcode 070: Subsets的方法一,区别在于这道题目中的给定数组是有重复元素的,因此在求子数组的时候对于重复元素需要处理。这种方法是我们从空数组开始,依次往当前已有的子数组中加入当前遍历到的元素,因此我们当遍历到重复元素时,若还是在当前已有的所有子数组加入该重复的元素,会导致有一部分的子数组时重复的。举个栗子:给定数组[1,2,2],从[ ]开始,我们首先遍历到元素1,往前已有的所有子数组中加入该元素,这是得到的所有子数组是[ ],[1];接下来遍历到元素2,我们还是在当前已有的所有子数组上加入当前遍历到的元素2,这是可以得到的所有子数组是[ ],[1],[2],[1,2];此时我们遍历到的接下来的元素还是2,若是我们还在当前所有子数组上加入该元素2,那么可以得到[ ],[1],[2],[1,2],,,[2,2],[1,2,2]。可以看到有重复的子数组,因此我们在用这种方法时要注意去掉这些重复子数组:就是在遍历到重复元素时,更新子数组集时只在上一轮得到的新的子数组上加该重复元素。代码如下:
class Solution:
def subsets2(self, nums: List[int]) -> List[List[int]]:
res = [[]]
nums.sort()
for i in range(len(nums)):
if i == 0 or nums[i] != nums[i - 1]:
l = len(res)
# 当遇到重复元素时,只需要在上一轮新生成的那几个子数组上加上该重复元素。因为在上上轮之前的子数组上加上该重复元素,与上一轮得到的子数组是重复的
res += [res[j] + [nums[i]] for j in range(len(res) - l, len(res))]
return res
方法二
对应于Leetcode 070: Subsets的方法二,深搜的方法,也是只需要先排序,注意去重的问题。
class Solution:
def subsets2(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort() # 为了方便后面去重,需要首先进行排序
def dfs(nums, temp, start):
res.append(temp[:])
for i in range(start, len(nums)):
if (i > start) and (nums[i] == nums[i-1]): # 去重
continue
temp.append(nums[i])
dfs(nums, temp, i + 1) # 到下一层
temp.pop() # 搜索到叶子节点后往回回溯
dfs(nums, [], 0)
return res