回溯算法的题目,这样做,秒杀( 五 )

也是完美解决!!
4 全排列问题先来一个最基本的全排列问题,快速解决 。
46. 全排列 难度中等

回溯算法的题目,这样做,秒杀

文章插图
 
这是全排列,只是元素的顺序不一样,所以,我们要做的剪枝就是:temp集合中有的就排除 。
上代码 。
    List<List<Integer>> lists = new ArrayList<>();    public List<List<Integer>> permute(int[] nums) {        if(nums.length == 0){            return lists;        }        List<Integer> list = new ArrayList<>();        backTrace(nums,list,0);        return lists;    }    public void backTrace(int[] nums, List<Integer> temp, int start){        if(temp.size() == nums.length){            lists.add(new ArrayList(temp));            return;        }        for(int i = 0; i < nums.length; i++){            //排除已有元素            if(temp.contains(nums[i])){                continue;            }            temp.add(nums[i]);            backTrace(nums,temp,i+1);            temp.remove(temp.size() - 1);        }    }是不是不带劲,安排!!
47. 全排列 II 难度中等这个题目虽然也是全排列,但是,就要比前面这个难一些了,有两个限定条件:有重复元素,但是不能包含重复排列 。
回溯算法的题目,这样做,秒杀

文章插图
 
不重复的全排列这个我们知道怎么解决,用前面的去重方法即可,但是,怎么保证有相同元素的集合不出现重复的排列呢?
这里我们需要加一个visited数组,来记录一下当前元素有没有被访问过,这样就可以解题了 。
  public List<List<Integer>> result = new ArrayList<>();    public List<List<Integer>> permuteUnique(int[] nums) {        if(nums.length == 0){            return result;        }        Arrays.sort(nums);        findUnique(nums,new boolean[nums.length],new LinkedList<Integer>());        return result;    }    public void findUnique(int[] nums, boolean[] visited,List<Integer> temp){        //结束条件        if(temp.size() == nums.length){            result.add(new ArrayList<>(temp));            return ;        }        //选择列表        for(int i = 0; i<nums.length; i++){            //已经选择过的不需要再放进去了            if(visited[i]) continue;            //去重            if(i>0 && nums[i] == nums[i-1] && visited[i-1]) break;                        temp.add(nums[i]);            visited[i] = true;            findUnique(nums,visited,temp);            temp.remove(temp.size()-1);            visited[i] = false;        }    }


推荐阅读