美文网首页
回溯算法之-排列

回溯算法之-排列

作者: 不知名的程序员 | 来源:发表于2021-03-14 11:05 被阅读0次

    回溯算法之-组合总和请看:https://www.jianshu.com/p/2a9856b96a86

    leetcode 46 全排列

    给定一个 没有重复数字的序列,返回其所有可能的全排列。

    先来说下排列和组合的区别,排列是给定可选择数组中每个数字都需要被使用;而组合则是根据题目要求可选择数组中数字的任意组合,并不是每个数字都需要,也并不是每个数字都需要使用。

    还是套用https://www.jianshu.com/p/2a9856b96a86
    一文中的回溯算法模板

    public List<List<Integer>> permute(int[] nums) {
            List<List<Integer>> res = new ArrayList<>();
                    // 排序非必须
            Arrays.sort(nums);
                    // 判断数组中元素是否被使用,这里也可以使用HashSet来判断(因为题干中提示无重复数字)
            int[] used = new int[nums.length];
            help(res, nums, new ArrayList<Integer>(), used);
            return res;
        }
    
        private void help(List<List<Integer>> res, int[] nums, ArrayList<Integer> list, int[] used) {
                    // 当集合元素=数组元素个数时,即代表这是一个全排列
            if (list.size() == nums.length) {
                res.add(new ArrayList<>(list));
                return;
            }
            for (int i = 0; i < nums.length; i++) {
                // 如果该元素已经被使用过了,跳过该元素
                            if (used[i] == 1) {
                    continue;
                }
                            // 标识该元素已经被使用
                used[i] = 1;
                list.add(nums[I]);
                help(res, nums, list, used);
                            // 回溯过后将该元素置为未使用
                used[i] = 0;
            list.remove(list.size()-1);
            }
        }
    

    Leetcode 47 全排列2

    与46题相比,区别在于给定数字包含重复元素
    套模板

    public List<List<Integer>> permute(int[] nums) {
            List<List<Integer>> res = new ArrayList<>();
                    // 排序非必须
            Arrays.sort(nums);
                    // 判断数组中元素是否被使用,这里也可以使用HashSet来判断(因为题干中提示无重复数字)
            int[] used = new int[nums.length];
            help(res, nums, new ArrayList<Integer>(), used);
            return res;
        }
    
        private void help(List<List<Integer>> res, int[] nums, ArrayList<Integer> list, int[] used) {
                    // 当集合元素=数组元素个数时,即代表这是一个全排列
            if (list.size() == nums.length) {
                res.add(new ArrayList<>(list));
                return;
            }
            for (int i = 0; i < nums.length; i++) {
                // 如果该元素已经被使用过了,跳过该元素
                            if (used[i] == 1) {
                    continue;
                }
                            // 这里是与上一题唯一不同的地方,需要进行去重,如果当前数字和前一个数字相等,并且前一个数字是已经回溯过的,则代表他们是树结构的同一层,则进行跳过
                if(i>0 && nums[i] == nums[i-1] && (used[i-1]==0)){
                    continue;
                }
                            // 标识该元素已经被使用
                used[i] = 1;
                list.add(nums[I]);
                help(res, nums, list, used);
                            // 回溯过后将该元素置为未使用
                used[i] = 0;
            list.remove(list.size()-1);
            }
        }
    

    相关文章

      网友评论

          本文标题:回溯算法之-排列

          本文链接:https://www.haomeiwen.com/subject/bshmqltx.html