LeetCode-047-全排列 II

雄獅虎豹發表於2021-10-18

全排列 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();
        }
    }
}
【每日寄語】 願太陽的光輝始終灑在你心上。願所有的不愉快,苦盡甘來。願每個脆弱的人都能得到善待。願現實有光,世界有暖。

相關文章