47.全排列-II
目录
47.全排列 II
47.全排列 II
给定一个可包含重复数字的序列
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
这个很难理解,要加一层判断:
if i > 0 and nums[i] == nums[i-1] and used[i - 1] == 0这里是因为横向遍历是顺序的,nums[i] == nums[i-1] and used[i - 1] == 0 说明前一个相同的节点i-1这个节点已经被使用过,这里就可以直接跳过i.
在全排列中used[i-1]==0 是区分树层相同元素访问和枝叶相同元素访问的关键。如果是在递归中访问到相同元素,那么used[i-1]一定等于1.
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
path = []
result = []
used = []
nums.sort()
for i in range(len(nums)):
used.append(0)
self.backtracking(nums, path, used, result)
return result
def backtracking(self, nums: List[int], path: List[int], used: List[int], result: List[List[int]]):
if len(path) == len(nums):
result.append(path.copy())
return
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i-1] and used[i - 1] == 0: # used[i - 1] == 0 说明i-1这个节点已经被使用过
continue
if used[i] == 0:
path.append(nums[i])
used[i] = 1
self.backtracking(nums, path, used, result)
path.pop()
used[i] = 0