回溯&全排列

146 阅读1分钟

前言

“这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

  1. 46. 全排列
  2. NC42 有重复项数字的所有排列(中等)

46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]]

示例 3: 输入:nums = [1] 输出:[[1]]

提示:

1 <= nums.length <= 6

-10 <= nums[i] <= 10

nums 中的所有整数 互不相同

思路分析:

回溯问题主要关心3点

  1. 已经做出的选择(记录在 temp 中)
  2. 结束条件(temp 中元素的个数 等于 数组的长度)
  3. 可以做出的选择(未在temp 中出现的元素)

AC 代码:

    List<List<Integer>> ans = new ArrayList<>();

    public List<List<Integer>> permute(int[] nums) {

        dfs(nums, new ArrayList<>());
        return ans;
    }

    void dfs(int[] nums, List<Integer> temp) {
        if (temp.size() == nums.length) {
            ans.add(new ArrayList<>(temp));
            return;
        }

        for (Integer num : nums) {
            if (!temp.contains(num)) {
                temp.add(num);
                dfs(nums, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }

有重复项数字的所有排列

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

NC42 与leetcode 上的 47 题一样 47. 全排列 II

示例 1:

输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]]

示例 2:

输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

思路分析:

存在重复的元素, 因此首先对数组排序, 其次在回溯的过程中 剪枝, 同一层不重复选择

与子集中剪枝一样 回溯问题主要关心3点

  1. 已经做出的选择(记录在 temp 中)
  2. 结束条件(temp 中元素的个数 等于 数组的长度)
  3. 可以做出的选择(同一层不存在重复的选择&&未使用的元素)

AC 代码:

    ArrayList<ArrayList<Integer>> ans = new ArrayList<>();

    boolean[] used;

    public ArrayList<ArrayList<Integer>> permuteUnique(int[] nums) {

        used = new boolean[nums.length];

        Arrays.sort(nums);
        dfs(nums, new ArrayList<>());
        return ans;
    }

    void dfs(int[] nums, ArrayList<Integer> temp) {
        if (temp.size() == nums.length) {
            ans.add(new ArrayList<>(temp));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
            if (!used[i]) {
                temp.add(num);
                used[i] = true;
                dfs(nums, temp);
                used[i] = false;
                temp.remove(temp.size() - 1);
            }
        }
    }