47. 全排列 II
题意
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
解题思路
去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。用编程的话描述就是第i个数与第j个数交换时,要求[i,j)中没有与第j个数相等的数。有两种方法(1)可以每次在需要交换时进行顺序查找;(2)用哈希表来查重;
回溯:遍历数组,判断是否能够交换,再两两交换给定对应下标的值;
回溯:思想和1一样;
回溯:遍历数组,两两交换给定对应下标的值,在加入最终结果的时候判断是否已经存在;
记忆化:通过遍历当前路径数组,遍历当前的路径数组选择位置来插入index对应的值实现;
实现
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def swap(start, end):
nums[start], nums[end] = nums[end], nums[start]
def can_swap(start, end):
for i in range(start, end):
if nums[i] == nums[end]:
return False
return True
def helper(index):
if index == len(nums):
res.append(nums[:])
return
for i in range(index, len(nums)):
# 避免出现相同的子数组
is_swap = can_swap(index, i)
if is_swap:
print is_swap
swap(i, index)
helper(index + 1)
swap(index, i)
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def helper(nums, index):
if index >= len(nums):
res.append(nums[:])
return
for i in range(index, len(nums)):
if i != index and nums[i] == nums[index]:
continue
# 有个问题,为什么在交换之后没有交换回来,是因为从一开始排序以后,就没有打算交换回来?
# 我的猜测是避免再次交换导致的重复的值出现
nums[i], nums[index] = nums[index], nums[i]
helper(nums[:], index + 1)
res = []
nums.sort()
helper(nums, 0)
return res
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
self.result=[]
self.helper(nums,0)
return self.result
def helper(self,nums,i):
if i ==len(nums)-1:
self.result.append(nums[:])
used=set()
for j in range(i,len(nums)):
if nums[j] not in used:
used.add(nums[j])
nums[i],nums[j]=nums[j],nums[i]
self.helper(nums[:],i+1)
nums[i],nums[j]=nums[j],nums[i]
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if not nums:
return []
res = [[]]
for n in nums:
temp = []
for cur in res:
for i in range(len(cur)+1):
temp.append(cur[:i] + [n] + cur[i:])
if i < len(cur) and cur[i] == n: # remove dups
break
res = temp
return res