【LeetCode題解】47. 全排列 II

給定一個可包含重複數字的序列,返回所有不重複的全排列。

示例:

輸入: [1,1,2]
輸出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/permutations-ii
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

class Solution {
    List<List<Integer>> ret = new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);//先排序
        int[] tmp = new int[nums.length];
        boolean[] vis = new boolean[nums.length];
        for(int i=0 ; i<nums.length ; i++){
            tmp[0] = nums[i];
            vis[i] = true;
            permute(nums, i ,tmp, 0, vis);
            vis[i] = false;
        }
        return ret;
    }
    
    void permute(int[] nums, int n, int[] cur, int k, boolean[] v){
        /** 
        這裏去重不可以單純判斷是否排序後的nums[i] == nums[i-1]
        因爲這是排列,不管是不是重複,[1,1]得排成[1,1]而不是第一個[1]出現後忽略第二個[1]
        評論中給了一個很好的思路,用另一個visited[]記錄上個元素是否被訪問過
        因爲是按照排序的順序選擇,所以上個元素i-1一旦被選擇過,必然是在上一輪選擇,則此時選擇i沒問題
        若上一個元素i-1未被選擇過,則必然是for循環分別訪問,則此時訪問i會出現重複
        */
        if(n!=0 && nums[n]==nums[n-1] && !v[n-1]){//與上一個數字相等且上一個數字未被訪問過
            return ;
        }
        if(k == cur.length-1){
            List<Integer> tmp = new ArrayList<>();
            for(int val:cur){
                tmp.add(val);
            }
            ret.add(new ArrayList<Integer>(tmp));
            return ;
        }
        for(int i=0 ; i<nums.length ; i++){
            if(v[i]){
                continue;
            }
            cur[k+1] = nums[i];
            v[i] = true; 
            permute(nums, i ,cur , k+1, v);
            v[i] = false; 
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章