题目详情
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
题目要求输入一个可能会有重复数字的数组nums,要求我们输出nums可能组成的全排列(无重复排列)。
思路
- 这道题和 46题全排列 的差别就在于它可能存在重复数字,所以我们就要考虑重复数字可能造成的重复排列的问题。
- 一种思路就是我在没次为我的结果集res添加新的排列的时候 判断新添加的排列 是否已经存在于结果集中了。可以用hashset来实现,但这种实现方式复杂度高。
- 另外一种实现思路是,新声明一个boolean数组isUsed来存储nums中元素的使用状况。然后在生成当前排列curr的时候就避免重复排列的产生。
- 以[1,1*,2]这个数组为例。
- 对于每次遍历的元素nums[i],我们要判断它是否等于nums[i-1],如果相等而且nums[i-1]被使用过的话,就可以组成一个未出现的排序(eg.[1,1]),如果nums[i-1]未被使用过,那么我们不会将nums[i]添加进排列,避免产生[1,1]这样的重复排列。
解法
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
boolean[] isUsed = new boolean[nums.length];
List<Integer> curr = new ArrayList<Integer>();
Arrays.sort(nums);
backtrack(res,isUsed,curr,nums);
return res;
}
public void backtrack(List<List<Integer>> res,boolean[] isUsed,List<Integer> curr,int[] nums){
if(nums.length == curr.size()){
res.add(new ArrayList<Integer>(curr));
return;
}
for(int i=0;i<nums.length;i++){
if(isUsed[i])continue;
if(i>0 && nums[i] == nums[i-1] && !isUsed[i-1])continue;
isUsed[i] = true;
curr.add(nums[i]);
backtrack(res,isUsed,curr,nums);
isUsed[i] = false;
curr.remove(curr.size()-1);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。