permutation II




class
Solution { public List<List<Integer>> permuteUnique(int[] nums) { Arrays.sort(nums); /////// sort it so we can skip the duplicate by comparing with the previous number List<List<Integer>> result = new ArrayList<>(); List<Integer> tmp = new ArrayList<>(); boolean[] used = new boolean[nums.length]; dfs(result, tmp, used, nums); return result; } private void dfs(List<List<Integer>> result, List<Integer> tmp, boolean[] used, int[] nums){ if(tmp.size() == nums.length){ // we can use tmp.size() to check if it has all the elements already result.add(new ArrayList<>(tmp)); return; } int prev = nums[0] - 1; // inital value nums[0] - 1 def not exist in the nums for(int i = 0; i < nums.length; i++){ // not used , and not the same value as the one before if(used[i] == false && nums[i] != prev){ // when i = 0, prev = nums[0] - 1. general case is nums.length> i > 0 tmp.add(nums[i]); used[i] = true; prev = nums[i]; dfs(result, tmp, used, nums);// prev is for the current level, so its passed withhin the for loop, not in the dfs passing, because we only care about if current pos has duplicates or not. current level: we care about if the the current element has been used, and if this element has the same value as the one before, since its sorted, we can use this trick to deduplicate // backtrack recovery tmp.remove(tmp.size() - 1); used[i] = false; } } } }

example:  1 1 1 2 

for the first pos, we can chose 1 and 2 , skip the two 1s in the middle , the way we skip these 1s is within the for loop,

 for(int i = 0; i < nums.length; i++){

we only add the nonduplicate ones to the list, when they satisfy  . notice there is no "else" statement, because else, we do nothing, dont add the element to the tmp list, so within the for loop, i++, 

 if(used[i] == false && nums[i] != prev){

for the second pos, prev's inital value is nums[0] - 1 again, 

say we chose the first 1 for the pos 1,and then for the second pos, we want to choose the second 1, when we check if the second 1  is valid or not, first  , we check if it has been used by checking if its index has been used, and then check if this 1 has the same value as previous element, at this moment, the prev = nums[0] - 1, which doesnt exist, so they are not equal, and then we know this 1 is valid. 

we do another dfs on this tmp list, so it goes to the next level (dont forget to mark the index of the element we pick as used)

on the current level, we are still on the pos 2, prev = 1 , we want to add the third 1 to the tmp, first we need to check if its index has been used from previous levels, if not, then we check if the value in the current index has the same value as the prev . in this case, they are the 

same, so we don't go into the if loop, we are back at for loop, i++, checking for other candidates on the same level with a different value as prev, so we can have a distinct permutation. 

 

because think this way: we have 1 1 1 3 3 

when we choose the first 1 for the pos 1, we have 1 1 3 3 left 

when we choose the second 1 for the pos 1, we have 1 1 3 3 left 

when we choose the third 1 for the pos 1, we have 1 1 3 3 left 

the permutation of 1  1 3 3 from the first combination is the same as the permutation of the second  and the third permutation,

so we really  need to pick one from them, which means we can skip the other two for the current level. 

Given a collection of numbers that might contain duplicates, return all possible unique permutations.


Example:


Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

example : 1112
if as in permutation one, which we dont have duplicates, for the first pos, we can try all elements in the array 
such as 1,1,1,2 . but we have duplicates 1 appeared three times, but only one time is needed, so we sort the array
and skip the duplicate values.

we still need to keep track of the number we used, for the next level, we use a boolean[] to keep track
which index we used already. if there are three '1', in the boolean array, we mark the first used 1's index as true
and for the next level, we look at the boolean[] used to check what other index has not been used yet .

how do we skip the duplicate elements on the same level after the array is sorted?
we can compare the current element with the prev element , and see if they have the same value
if they do, skip the current element


 

posted on 2018-08-11 04:29  猪猪&#128055;  阅读(179)  评论(0)    收藏  举报

导航