leetcode 47 Permutations II

題目詳情

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);
        }
    }
相關文章
相關標籤/搜索