【leetcode】47. Permutations II

網址

題目

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]
]

解法

嘻嘻 最簡單的方法就是跟之前一樣的做,但是如果res中該存在該組合則加進去,如果不存在就不加

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums == null || nums.length == 0) return res;
        recursiveSwap(nums, 0, res);
        return res;        
    }
    
    private void recursiveSwap(int[] nums, int pos, List<List<Integer>> res){
        if(pos > nums.length-1){
            List<Integer> temp = new ArrayList<>();
            for(int i=0; i<nums.length;i++){
                temp.add(nums[i]);
            }
            if(!res.contains(temp)) res.add(temp);
            return;
        }
        for(int i=pos; i<nums.length;i++){
            int tmp = nums[pos];
            nums[pos] = nums[i];
            nums[i] = tmp;     
            
            recursiveSwap(nums, pos+1, res);
            
            tmp = nums[pos];
            nums[pos] = nums[i];
            nums[i] = tmp;                
        }
    }
}

發現之前寫的代碼都有點小問題,還是排列的順序上,因爲每次都只是交換兩個數字,假設原數組按順序排列,如果交換的是非相鄰項,那整體不一定是從小到大的順序。但是leetcode貌似並未考覈順序的排列,所以能夠通過實例。

還是參考該作者的博文 https://www.jianshu.com/p/a08d7fd65572 該問題無非是樹的剪枝,那麼該如何剪枝呢?
在這裏插入圖片描述
剛開始考慮先排序,每次交換檢查當前值與前一個值的大小,如果相等就跳過;但是考慮這樣的情景:我們現在在遍歷3個子樹中最左邊的一個,此時我們要交換1和2,1和前一個值一樣就被跳過去了;所以我們需要有一個數組來記錄當前遍歷的是哪棵樹,有沒有遍歷完全。

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {

        List<List<Integer>> result = new ArrayList<>();

        if (nums == null || nums.length == 0) {
            return result;
        }

        boolean[] visited = new boolean[nums.length];
        List<Integer> temp = new ArrayList<>();
        Arrays.sort(nums);
        permuteRecursively(nums, visited, temp, result);

        return result;
    }

    private void permuteRecursively(int[] nums, boolean[] visited, 
                              List<Integer> temp, List<List<Integer>> result) {

        if (temp.size() >= nums.length) {
            result.add(new ArrayList<>(temp));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            // 前一層遞歸已經訪問過,跳過
            if (visited[i]) {
                continue;
            }
            // i和前面的相同,但是前面的沒有訪問,
            // 只能是因爲前面的已經退出來了,那這個也就跳過
            if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
                continue;
            }
            visited[i] = true;
            temp.add(nums[i]);
            permuteRecursively(nums, visited, temp, result);
            temp.remove(temp.size() - 1);
            visited[i] = false;
        }

    }

}

自己嘗試在上一次的基礎上加老是出問題,由於leetcode訪問不穩定,總是提交不了 耗了太長時間也就作罷。。。

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