zoukankan      html  css  js  c++  java
  • LeetCode-047-全排列 II

    全排列 II

    题目描述:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

    示例说明请见LeetCode官网。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/permutations-ii/
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解法一:穷举法
    • 首先,构造一棵多叉树MultiTree,该多叉树有以下几个属性,used表示当前路径已经走过的数组的位置,paths表示当前路径中的数字。
    • 然后声明一个队列queue,队列的元素就是MultiTree,首先将nums中不同的数字出初始化成路径的第一个数字,然后加入到队列中(需要同时初始化used和paths)。
    • 然后遍历队列queue,按照类似的方式将数组nums中没用到的数字加入到当前路径中(需要判断重复数字)。
    • 直到队列中每一条路径的长度都和nums的长度一样,即已将所有的数字加入到路径中。
    • 最后,返回队列中的所有的路径paths。

    说明:其实本来想构造一棵多叉树,所有叶子节点到根节点的路径即为所有的路径排列,后来没用到,所以没有构造树的父子关系 。

    import java.util.*;
    
    public class LeetCode_047 {
    
        /**
         * 构造一棵多叉树
         */
        static class MultiTree {
            // 当前的值
            public Integer val;
    
            public MultiTree parent;
    
            // 当前路径已经走过的数组的位置
            public List<Integer> used;
    
            // 当前路径中的数字
            public List<Integer> paths;
    
            public MultiTree(Integer val) {
                this.val = val;
                used = new ArrayList<>();
                paths = new ArrayList<>();
            }
        }
    
        public static List<List<Integer>> permuteUnique(int[] nums) {
            Queue<MultiTree> queue = new LinkedList<>();
            Arrays.sort(nums);
            int curNum = nums[0];
            // 第一条路径
            MultiTree first = new MultiTree(nums[0]);
            first.paths.add(nums[0]);
            first.used.add(0);
            queue.add(first);
            // 其他路径
            for (int i = 1; i < nums.length; i++) {
                if (nums[i] != curNum) {
                    MultiTree next = new MultiTree(nums[i]);
                    next.paths.add(nums[i]);
                    next.used.add(i);
                    queue.add(next);
                    curNum = nums[i];
                }
            }
    
            int length = 1;
    
            while (length < nums.length) {
                int count = queue.size();
                while (count > 0) {
                    MultiTree curNode = queue.poll();
                    int firstNum = -1, firstNumIndex = -1;
                    // 找到第一个已有路径没经过的数
                    for (int i = 0; i < nums.length; i++) {
                        if (!curNode.used.contains(i)) {
                            firstNum = nums[i];
                            firstNumIndex = i;
                            MultiTree firstTree = new MultiTree(nums[i]);
                            firstTree.paths.addAll(curNode.paths);
                            firstTree.paths.add(firstNum);
                            firstTree.used.addAll(curNode.used);
                            firstTree.used.add(firstNumIndex);
                            queue.add(firstTree);
                            break;
                        }
                    }
    
                    // 将其他不同的数也添加到新的路径
                    for (int i = firstNumIndex + 1; i < nums.length; i++) {
                        if (!curNode.used.contains(i) && nums[i] != firstNum) {
                            MultiTree otherTree = new MultiTree(nums[i]);
                            otherTree.paths.addAll(curNode.paths);
                            otherTree.paths.add(nums[i]);
                            otherTree.used.addAll(curNode.used);
                            otherTree.used.add(i);
                            queue.add(otherTree);
                            firstNum = nums[i];
                        }
                    }
                    count--;
                }
                length++;
            }
    
            List<List<Integer>> result = new ArrayList<>();
            while (!queue.isEmpty()) {
                result.add(queue.poll().paths);
            }
            return result;
        }
    
        public static void main(String[] args) {
            int[] nums = new int[]{1, 1, 2};
            for (List<Integer> integers : permuteUnique(nums)) {
                for (Integer integer : integers) {
                    System.out.print(integer + " ");
                }
                System.out.println();
            }
        }
    }
    

    【每日寄语】 愿太阳的光辉始终洒在你心上。愿所有的不愉快,苦尽甘来。愿每个脆弱的人都能得到善待。愿现实有光,世界有暖。

  • 相关阅读:
    对象并不一定都是在堆上分配内存的
    Minor GC、Major GC和Full GC之间的区别
    JAVA内存分配与回收策略
    HotSpot虚拟机对象相关内容
    JAVA运行时数据区域
    Java 的强引用、弱引用、软引用、虚引用
    去哪儿网支付系统架构演进(下篇)
    去哪儿网支付系统架构演进(上)
    心智模式:如何改善我们的心智模式?
    心智模式:心智模式成熟的标志
  • 原文地址:https://www.cnblogs.com/kaesar/p/15396053.html
Copyright © 2011-2022 走看看