题目:
给定一个可包含重复数字的序列 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations-ii
思路:利用回溯算法,需要记录的有两处:
1、已经添加到序列中的位置 index ,这里存放到集合当中,用于避免重复把同一位置的数据添加到结果中;
2、在同一层中添加过的元素,不再重复的循环迭代,以免出现重复的排列
Java代码如下:
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
permuteUniqueBack(nums,result,new ArrayList<>(),new HashSet<>());
return result;
}
public void permuteUniqueBack(int[] nums,List<List<Integer>> result,List<Integer> tmp,Set<Integer> set){
if(tmp.size() == nums.length){
result.add(new ArrayList<>(tmp));
return;
}else if(tmp.size()>nums.length){
return;
}
Set<Integer> sset = new HashSet<>();
for(int i=0;i<nums.length;i++){
if(set.contains(i) || sset.contains(nums[i])){
continue;
}
sset.add(nums[i]);
set.add(i); //记录当前的位置
tmp.add(nums[i]);
permuteUniqueBack(nums,result,tmp,set);
set.remove(i);
tmp.remove(tmp.size()-1);
}
}
}