題目詳情
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
題目要求輸入一個可能會有重複數字的數組nums,要求咱們輸出nums可能組成的全排列(無重複排列)。
思路
- 這道題和 46題全排列 的差異就在於它可能存在重複數字,因此咱們就要考慮重複數字可能形成的重複排列的問題。
- 一種思路就是我在沒次爲個人結果集res添加新的排列的時候 判斷新添加的排列 是否已經存在於結果集中了。能夠用hashset來實現,但這種實現方式複雜度高。
- 另一種實現思路是,新聲明一個boolean數組isUsed來存儲nums中元素的使用情況。而後在生成當前排列curr的時候就避免重複排列的產生。
- 以[1,1*,2]這個數組爲例。
- 對於每次遍歷的元素nums[i],咱們要判斷它是否等於nums[i-1],若是相等並且nums[i-1]被使用過的話,就能夠組成一個未出現的排序(eg.[1,1]),若是nums[i-1]未被使用過,那麼咱們不會將nums[i]添加進排列,避免產生[1,1]這樣的重複排列。
解法
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
boolean[] isUsed = new boolean[nums.length];
List<Integer> curr = new ArrayList<Integer>();
Arrays.sort(nums);
backtrack(res,isUsed,curr,nums);
return res;
}
public void backtrack(List<List<Integer>> res,boolean[] isUsed,List<Integer> curr,int[] nums){
if(nums.length == curr.size()){
res.add(new ArrayList<Integer>(curr));
return;
}
for(int i=0;i<nums.length;i++){
if(isUsed[i])continue;
if(i>0 && nums[i] == nums[i-1] && !isUsed[i-1])continue;
isUsed[i] = true;
curr.add(nums[i]);
backtrack(res,isUsed,curr,nums);
isUsed[i] = false;
curr.remove(curr.size()-1);
}
}