[leedcode 47] Permutations II
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]
.
public class Solution { List<Integer> seq; List<List<Integer>> res; public List<List<Integer>> permuteUnique(int[] nums) { //如果不需要seq,只需在每次start>end时,构造新的List<integer>,初始值为nums,再将该list放入结果中 //本题和之前的无重复全排列,有几处不同 //1.需要排列 //2.当start和后面进行交换时,注意去重,如果此时的nums[i]==nums[i-1]说明和之前的是相同的,此时不需要交换 //3.虽然第二步已经去重,但是考虑到交换之后,相同的值被分割的情况,还是会有重复的结果的,因此,在start>end时,需要再一步去重 //有的解法是利用hashset,每一步通过判断hashset是否存在该值(该值得范围是start到end),决定是否要交换。 seq=new ArrayList<Integer>(); res=new ArrayList<List<Integer>>(); Arrays.sort(nums); findpremute(nums,0,nums.length-1); return res; } public void findpremute(int[] nums,int start,int end){ if(start>end){ // if(!res.contains(seq))//注意去重,使用hashset不需要此句 res.add(new ArrayList<Integer>(seq)); return ; } HashSet<Integer> set=new HashSet<Integer>(); for(int i=start;i<=end;i++){ if(!set.contains(nums[i])){//00019 90010此时0和之前的1不同,因此结果处需要去重 set.add(nums[i]); swap(nums,start,i); seq.add(nums[start]); findpremute(nums,start+1,end); seq.remove(seq.size()-1); swap(nums,start,i); } } /* for(int i=start;i<=end;i++){ if(i==start||i>start&&nums[i]!=nums[i-1]){//00019 90010此时0和之前的1不同,因此结果处需要去重 swap(nums,start,i); seq.add(nums[start]); findpremute(nums,start+1,end); seq.remove(seq.size()-1); swap(nums,start,i); } }*/ } public void swap(int[] nums,int i,int j){ int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; } }