class Solution {
boolean[] used;
List<List<Integer>> res = new LinkedList<>();
List<Integer>tmp = new ArrayList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
used = new boolean[nums.length];
helper(nums,0);
return res;
}
private void helper(int[] nums, int count) {
if(count==nums.length){
res.add(new ArrayList(tmp));
return;
}
for (int i=0;i<nums.length;i++){
if(i>0&&nums[i]==nums[i-1]&&!used[i-1])
continue;
if (!used[i]) {
tmp.add(nums[i]);
used[i] = true;
helper(nums, count + 1);
used[i] = false;
tmp.remove(tmp.size() - 1);
}
}
}
}
本题最重要的步骤是 if(i>0&&nums[i]==nums[i-1]&&!used[i-1]) ,这句代码主要是用来剪枝,减少大量重复计算。其中!used[i-1]又是本行代码最重要的步骤,它主要是为了区分重复数字是本层循环还是下层循环,若是下层循环表示该数字虽然是重复数字,但是并未使用过,所以是可填的,不应跳过。否则是本层循环,因为与前面数字重复,所以可以直接跳过。