1. 程式人生 > >全排列 II

全排列 II

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

示例:

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

參考全排列
在全排列I的基礎上加判斷當前操作元素是否前面已經存在重複即可,不存在在執行換位操作,存在跳過即可;

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        int end = nums.length - 1;
        List<List<Integer>> res = new ArrayList<>();
        permute(nums, res, 0, end);
        return res;
    }
        
    //換位
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    
    public void permute(int[] nums, List<List<Integer>> res, int begin, int end) {
        //遞迴法,兩兩換位
        //遞迴結束條件,兩兩換位後,begin = end;
        if (begin == end) {// 完成一次全排列
            List<Integer> temp = new ArrayList<>();
            for (Integer i : nums)
                temp.add(i);
            res.add(temp);
            return;
        } else {
            for (int i = begin; i <= end; i ++) {//換位
                if (checkContains(nums, begin, i)) {                
                    swap(nums, begin, i);//鎖定位              
                    permute(nums, res, begin + 1, end);//後續位                
                    swap(nums, begin, i);//回檔在進行下次換位
                }
            }
        }
    }
    
    private boolean checkContains(int[] nums, int start, int end) {
        for (int i = start; i < end; i ++) {
            if (nums[i] == nums[end])//當前元素已經是重複元素
                return false;
        }
        return true;
    }
}