5

LeetCode-047-全排列 II

 2 years ago
source link: https://segmentfault.com/a/1190000040797282
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

LeetCode-047-全排列 II

发布于 10 月 11 日

全排列 II

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

示例说明请见LeetCode官网。

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

解法一:穷举法
  • 首先,构造一棵多叉树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();
        }
    }
}

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK