在全排列I基础上判断集合中是否存在重复,添加不重复元素即可。
方法一: 利用Set,简单效率低
public static List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
Set<List<Integer>> ll = new HashSet<>();
boolean[] v = new boolean[nums.length];
dfs(ll,new ArrayList<Integer>(),nums,v);
List<List<Integer>> r = new ArrayList<>();
Iterator it = ll.iterator();
while (it.hasNext()){
r.add((List<Integer>)it.next());
}
return r;
}
public static void dfs(Set<List<Integer>> ll,List<Integer> l,int[] nums,boolean[] v){
if(l.size() == nums.length){
ll.add(new ArrayList<>(l));
}
for(int i=0;i<nums.length;i++){
if(v[i])continue;
l.add(nums[i]);
v[i]=true;
dfs(ll,l,nums,v);
l.remove(l.size() - 1);
v[i] = false;
}
}
方法二:利用经典去重
当本次nums[i]已经被选用时,跳过本次循环。
当本次nums[i]和nums[i-1]重复,且v [i-1]已经被使用了,跳过本次循环。
public static List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> ll = new ArrayList<>();
boolean[] v = new boolean[nums.length];
dfs(ll,new ArrayList<Integer>(),nums,v);
return ll;
}
private static void dfs(List<List<Integer>> ll, ArrayList<Integer> l, int[] nums, boolean[] v) {
if(l.size()== nums.length){
ll.add(new ArrayList<>(l));
return;
}
for (int i = 0; i < nums.length; i++) {
if(v[i])continue;
if(i>0 && nums[i-1]==nums[i] && v[i-1])continue;
l.add(nums[i]);
v[i]=true;
dfs(ll,l,nums,v);
l.remove(l.size()-1);
v[i]=false;
}
}