[Leetcode] Permutations II
The difference betweent Problem Permutation I and Permuation II lies in the duplicates elements may exist in the second one.
For the first one , the enumeration strategy is applied. This one can also reuse that method. However, the difficulty here is how to avoid the selection of the same element as the head of the list.
We can sort the list first, when faced with the same element with the head one, we just skip it. Amazing attribute of this method is the we just need to swap the head current and the selected next element without swap back operation, as after next swap ,the left list is still in order. We can take an example
1,1,2,2,2,3,4
we select 1, 1,2,2,2,3,4
we select 2, swap 1 and 2,get
2, 1,1,2,2,3,4
we selct 3, swap 2 and 3,get
3, 1,1,2,2,2,4
we select 4,swap 3 and 4,get
4, 1,1,2,2,2,3
the swap back operation is not conducted, but the remaining part is still sorted. The reason lies in that the head element is swap back to its right position during the next head swap.
The code is listed as below.
1 public class Solution { 2 private void backtrack(List<List<Integer> > lists, List<Integer> list, int [] nums, int index){ 3 if(index==nums.length){ 4 List<Integer> l = new LinkedList<Integer>(); 5 l.addAll(list); 6 lists.add(l); 7 return; 8 } 9 //Arrays.sort(nums,index,nums.length); 10 for(int i=index;i<nums.length;i++){ 11 12 if(i!=index&&nums[i]==nums[index]){ 13 continue; 14 } 15 int tmp=nums[index]; 16 nums[index]=nums[i]; 17 nums[i]=tmp; 18 list.add(nums[index]); 19 backtrack(lists,list,nums,index+1); 20 list.remove(list.size()-1); 21 } 22 Arrays.sort(nums,index,nums.length); 23 } 24 public List<List<Integer>> permuteUnique(int[] nums) { 25 Arrays.sort(nums); 26 List<List<Integer> > lists =new LinkedList<List<Integer> >(); 27 List<Integer> list = new LinkedList<Integer>(); 28 backtrack(lists,list,nums,0); 29 return lists; 30 } 31 }
After each for loop we should sort the disordered list into ordered, because in the up recursive layer, the algorithm need the sorted element.
A more simple Solution
1 public class Solution { 2 private void DFS(List<List<Integer>> res, int []nums,int start){ 3 if(start==nums.length){ 4 List<Integer> tmpres = new LinkedList<Integer>(); 5 for(int num: nums) tmpres.add(num); 6 res.add(tmpres); 7 return; 8 } 9 for(int i=start;i<nums.length;i++){ 10 if(i!=start&&nums[i]==nums[start]) continue; 11 int tmp = nums[start]; 12 nums[start]=nums[i]; 13 nums[i]=tmp; 14 DFS(res,nums,start+1); 15 } 16 Arrays.sort(nums,start,nums.length); 17 } 18 public List<List<Integer>> permuteUnique(int[] nums) { 19 //sort the array first 20 Arrays.sort(nums); 21 List<List<Integer>> res = new LinkedList<List<Integer>>(); 22 DFS(res,nums,0); 23 return res; 24 } 25 }