版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a786150017/article/details/82961812
题目描述
有重复数字的全排列
例子
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
解法
法1 - 类似于有重复数字的全排列,最后再处理重复的排列。但比较耗时,不是最优解法
法2 - 改进法1,注意不能判断把pos!=i and nums[pos] == nums[i]作为continue的判别标准,比如2,1,1-自己画图看一下
解法1-1
类似于有重复数字的全排列,此处采用递归解法
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.dfs(nums, 0, res)
return list(map(list, set(res)))
def dfs(self, nums, pos, res):
if pos == len(nums):
res.append(tuple(nums))
for i in range(pos, len(nums)):
nums[pos], nums[i] = nums[i], nums[pos]
self.dfs(nums, pos+1, res)
nums[pos], nums[i] = nums[i], nums[pos]
解法1-2
非递归,固定某数字,依次在可能位置插入下一个数字
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
lastPerms = [[]]
for num in nums:
perms = []
for lastPerm in lastPerms:
for i in range(len(lastPerm)+1):
perms.append(lastPerm[:i] + [num] + lastPerm[i:])
lastPerms = perms
return list(set(map(tuple, lastPerms)))
解法2-1
定义一个visited,判断是否重复
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.dfs(nums, 0, res)
return res
def dfs(self, nums, pos, res):
if pos == len(nums):
res.append(nums[:])
visited = set()
for i in range(pos, len(nums)):
if nums[i] in visited:
continue
visited.add(nums[i])
nums[pos], nums[i] = nums[i], nums[pos]
self.dfs(nums, pos+1, res)
nums[pos], nums[i] = nums[i], nums[pos]
解法2-2
非递归改进,固定某数字,依次在可能位置插入下一个数字。但是不在和num重复的数字后插入num
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
lastPerms = [[]]
for num in nums:
perms = []
for lastPerm in lastPerms:
for i in range(len(lastPerm)+1):
perms.append(lastPerm[:i] + [num] + lastPerm[i:])
if i < len(lastPerm) and num == lastPerm[i]:
break
lastPerms = perms
return lastPerms