Given a collection of numbers, nums, that might contain duplicates, return all possible unique permutations in any order.
Example 1:
Input: nums = [1,1,2]
Output:
[[1,1,2],
[1,2,1],
[2,1,1]]
大致意思是在全排列的基础上去重,如果先得到所有全排列,再去重,这样的效率是极低的,也是通过不了的。比较好的方法是在全排列的过程中进行裁剪分支,将重复的分支去除掉。
先回顾一下全排列,它的思想是这样的:对于n个数进行全排列,对于第一个位置,它有n种选择,选完之后,还剩n-1个数,对于第二个位置,它有n-1种选择,以此类推,共有n!种排列。从算法设计上,肯定需要选择递归回溯算法。对于第i个位置,它有n-i种选择,我们依此将i之后(包括i)的元素与第i个元素交换,这种交换思想起到了给第i个位置选择n-i种元素的作用。比如:我们选择第i+1个元素与第i个元素交换,然后通过递归进入后续的排列,当后续的排列完成时,通过再次交换回到之前状态,然后才可以选择第i+2个元素,重复以上过程。
参考代码:
def permute(self, nums: list):
def mySwap(nums, left, right):
temp = nums[left]
nums[left] = nums[right]
nums[right] = temp
def permute_reverse(nums, begin, end, res):
if (begin == end):
res.append(list(nums))
else:
for i in range(begin,end):
mySwap(nums, i, begin)
permute_reverse(nums, begin + 1, end, res)
mySwap(nums, i, begin)
res = []
permute_reverse(nums, 0, len(nums), res)
return res
如果能理解全排列的思想的话,理解全排列去重也就轻松多了,我接着上面的讲,对第i个位置元素的选择,如果我们选择了重复的元素的话,那最终的排列就会重复,要解决这种问题,我们只对每种元素选择一次就好了,也就是说对于(n-i)个候选元素,对其去重,可以把它当作字典或set集。
参考代码:
def permuteUnique(self, nums: list):
def mySwap(nums, left, right):
temp = nums[left]
nums[left] = nums[right]
nums[right] = temp
def permute_reverse(nums, begin, end, res):
process = dict()
if (begin == end):
res.append(list(nums))
else:
for j in range(begin,end):
if nums[j] not in process:
process[nums[j]]=1
mySwap(nums, j, begin)
permute_reverse(nums, begin + 1, end, res)
mySwap(nums, j, begin)
res = []
#nums.sort()
permute_reverse(nums, 0, len(nums), res)
return res
该博客探讨了如何在生成全排列的同时去除重复元素的问题,提供了一种在递归过程中利用字典记录已选择元素的方法,以提高效率。示例代码展示了如何在Python中实现这一算法,适用于处理包含重复元素的数列的全排列问题。

1293

被折叠的 条评论
为什么被折叠?



