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 resultdef backtracking(self, nums: List[int], path: List[int], used: List[int], result: List[List[int]]):if len(path) == len(nums):result.append(path.copy())returnfor 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这个节点已经被使用过continueif used[i] == 0:path.append(nums[i])used[i] = 1self.backtracking(nums, path, used, result)path.pop()used[i] = 0