有重复项数字的全排列-牛客
思路
- 递归+回溯
1:先对数组升序排列,num.sort()。
2:准备一个临时数组temp暂存递归过程中组装的排列情况;使用额外的vis数组用于记录哪些位置的数字被加入了。
3:每次递归从头遍历原数组,获取数字加入:首先根据vis数组,已经加入的元素不能再次加入了;其次,如果当前的元素num[i]与同一层的前一个元素num[i-1]相同且num[i-1]已经用,也不需要将其纳入。
4:进入下一层递归前将vis数组当前位置标记为使用过。
5:回溯的时候需要修改vis数组当前位置标记,同时去掉刚刚加入数组的元素。
6:临时数组长度到达原数组长度就是一种排列情况,此时递归终止,return
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param num int整型一维数组
# @return int整型二维数组
#
class Solution:
def permuteUnique(self , num: List[int]) -> List[List[int]]:
# 递归+回溯
if len(num)==1:
return [num]
#排序,升序
num.sort()
res=list(list())
temp=list()
#记录元素是否使用过,0-未使用,1-使用过
vis=[0]*len(num)
self.recursion(res, num, temp, vis)
return res
def recursion(self, res, num, temp, vis):
#临时数组长度等于原数组长度,表示找到一个排列,加入结果数组
if len(temp)==len(num):
res.append(temp.copy())
return
#遍历原数组
for i in range(len(num)):
if vis[i]==1:
#该元素被使用过
continue
if i > 0 and num[i]==num[i-1] and vis[i-1]==1:
#当前元素与前一个元素相同,且前一个元素已使用过
continue
#标记为已使用过
vis[i]=1
#加入临时数组
temp.append(num[i])
self.recursion(res, num, temp, vis)
#回溯
vis[i]=0
temp.pop()