47. 全排列 II
Difficulty: 中等
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
Solution
这题跟46题如出一辙,只不过题目给定的数组中有重复元素,按照46题的解法结果中会有重复元素。解决的办法是先对给定的数组排序,然后在进行深度优先搜索的时候如果当前元素和上个元素相同那么就不往下搜索了,这样就避免了结果中出现的重复元素。
解法一:
如果这个数和之前的数一样,并且之前的数还未使用过,那接下来如果走这个分支,就会使用到之前那个和当前一样的数,就会发生重复,此时分支和之前的分支一模一样。
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
nums.sort()
used = [False] * len(nums)
self.res = []
self.dfs(nums, [], used, self.res)
return self.res
def dfs(self, nums, path, used, res):
if len(path) == len(nums):
res.append(path[:])
return
for i in range(len(nums)):
if not used[i]:
if i > 0 and nums[i-1] == nums[i] and not used[i-1]:
continue
used[i] = True
path.append(nums[i])
self.dfs(nums, path, used, res)
used[i] = False
path.pop()
解法二:
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
if not nums:
return []
nums.sort()
res = []
self.dfs(nums, [], res)
return res
def dfs(self, nums, path, res):
if not nums:
res.append(path)
return
for i, e in enumerate(nums):
if i > 0 and nums[i-1] == nums[i]:
continue
else:
self.dfs([num for j, num in enumerate(nums) if j != i], path + [e], res)