47.全排列 II
  1. 全排列 II

难度中等281

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
此问题和46是相同的思路,使用回溯法 在查找所有解的时候 使用剪枝 取出掉不符合的条件。

代码的实现主要是通过一个boolean数组来判断。如果访问过 continue 如果当前和上一个元素相等  并且上一个元素已经visited 直接continue 。否则就添加。剩下就是回溯法的模板代码。

选择 》 进入下层决策树 》撤销树

List<List<Integer>> result = new ArrayList<>();
    //backtrack
    public List<List<Integer>> permuteUnique(int[] nums) {
        if(nums.length == 0 || nums == null)    return null;
        Arrays.sort(nums);
        findUnique(nums,0,new boolean[nums.length],new LinkedList<Integer>());
        return result;
    }

    private void findUnique(int [] nums,int start,boolean [] visited,LinkedList<Integer>  track){
        //1.终止条件
        if(nums.length ==  track.size()){
            result.add(new LinkedList<>(track));
            return;
        }

        for(int i=0;i<nums.length;i++){
            //如果访问过 直接continue
            if(visited[i]) continue;
            //如果当前节点和前一个节点相等 并且 前一个节点已经被访问过了,直接continue
            if(i>0 && nums[i] == nums[i-1] && visited[i-1])  continue;
            
            //选择
            track.add(nums[i]);
            visited[i] = true;
            //进入下一层决策树
            findUnique(nums,i+1,visited,track);
            //撤销选择
            track.removeLast();
            visited[i] = false;
        }
    }