Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2]
, [1,2,1]
, and [2,1,1]
.
=================
Idea is to reuse the [leet code] Permutations approach and add the handling for duplicate numbers.
We reused the second solution in problem Permutations, which is to keep switching the numbers in order to construct a new permutation. To handle the duplicated numbers in problem Permutations II, we can just skip the duplicated numbers that we have previously switched. For example, in case of [0,1,1,2], our program should switch 0 with the first 1, then skip the second 1, then switch with 2 (switch 2 times only).
Another thing need to be considered is that the sub-array is not sorted during recursive call. Therefore, we need a mechanism to detect the duplicated number rather than just comparing the previous number and current number (e.g. 1,0,1,2). Accordingly, we can use a temporary hash set to keep the numbers that we previously switched, and check it every time before we try to switch number.
public class Solution {
public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
ArrayList<ArrayList<Integer>> rs = new ArrayList<ArrayList<Integer>>();
Arrays.sort(num);
helper(rs, num, 0);
return rs;
}
public void helper(ArrayList<ArrayList<Integer>> rs, int[] num, int index){
if(index == num.length){
ArrayList<Integer> singlePer = new ArrayList<Integer>();
for(int i=0; i<num.length; i++) singlePer.add(num[i]);
rs.add(singlePer);
}
else{
HashSet<Integer> dupTest = new HashSet<Integer>(); // check duplicate
for(int i=index; i<num.length; i++){
if(dupTest.contains(num[i])) continue;// skip duplicate
else{
dupTest.add(num[i]); // check duplicate
int temp = num[index];
num[index] = num[i];
num[i] = temp;
helper(rs, num, index+1);
num[i] = num[index];
num[index] = temp;
}
}
}
}
}