LeetCode--47.全排列 II(回溯算法)

47.全排列 II

题目描述

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

示例 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]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

代码

java 复制代码
class Solution {

    // 存放最终所有不重复排列结果
    List<List<Integer>> result = new ArrayList<>();

    // 当前路径(当前排列)
    List<Integer> path = new ArrayList<>();


    /**
     * 回溯函数
     *
     * @param nums 排序后的数组
     * @param used used[i] 表示 nums[i] 是否已经被使用
     */
    public void backtracking(int[] nums, int[] used){

        /**
         * 终止条件
         *
         * 当当前路径长度等于数组长度时,
         * 说明已经形成一个完整排列
         */
        if(path.size() == nums.length){

            // 加入结果集
            result.add(new ArrayList<>(path));

            return;
        }


        /**
         * 全排列:
         * 每一层都从 0 开始搜索
         */
        for(int i = 0; i < nums.length; i++){

            /**
             * 树层去重(核心)
             *
             * nums[i] == nums[i - 1]
             *      说明当前元素和前一个元素相同
             *
             * used[i - 1] == 0
             *      说明前一个元素已经回溯结束,
             *      即:
             *      当前两个相同元素处于同一树层
             *
             * 同一层中,相同元素只使用一次
             */
            if(i > 0
                    && nums[i] == nums[i - 1]
                    && used[i - 1] == 0){
                continue;
            }


            /**
             * 如果当前元素还未使用
             */
            if(used[i] == 0){

                // 做选择:加入当前元素
                path.add(nums[i]);

                // 标记当前元素已使用
                used[i] = 1;

                // 递归下一层
                backtracking(nums, used);

                // 回溯:恢复现场

                // 当前元素恢复未使用状态
                used[i] = 0;

                // 删除路径最后一个元素
                path.remove(path.size() - 1);
            }
        }
    }


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

        /**
         * 必须先排序
         *
         * 这样相同元素才能相邻,
         * 后续树层去重才能生效
         */
        Arrays.sort(nums);


        /**
         * used数组:
         *
         * used[i] == 1
         *      nums[i] 已经在当前路径中
         *
         * used[i] == 0
         *      nums[i] 还未使用
         */
        int[] used = new int[nums.length];

        backtracking(nums, used);

        return result;
    }
}
相关推荐
海绵天哥9 小时前
LeetCode Hot 100 | 链表(下)· 分组翻转与设计(C++ 题解)
c++·leetcode·链表
就改了15 小时前
Java8 日期处理(详细版)
java·python·算法
2601_9583529016 小时前
接上USB,焊上麦,通话瞬间安静——WX-0813如何用AI降噪+100dB消回音,把嘈杂通话变成“金子“般清晰
人工智能·算法·语音识别·硬件开发·语音模块·降噪消回音
小蒋学算法17 小时前
算法-M个非重叠子数组最大和II-WQS二分学习
数据结构·学习·算法
我要见SA姐118 小时前
AI提示词遇见精密算法:TimeGuessr如何用数学魔法打造文化游戏新体验
人工智能·算法·游戏
Jerry18 小时前
LeetCode 56. 合并区间
算法
实验如有神祝女士1 天前
不同参数规模大模型在医学翻译场景的适配差异
论文阅读·人工智能·深度学习·学习·算法·语言模型·论文笔记
windliang1 天前
Claude Code 源码分析(三):一次模型回答如何流进 Agent
前端·算法·ai编程
Kyrie_kk1 天前
Java--BigInteger 超大整数计算
java·算法
汽车网络安全爱好者1 天前
Public Key Infrastructure(二)— 深入理解 X.509 证书:从 RFC 5280 到 OpenSSL 实践
运维·服务器·算法·网络安全·汽车·密码学·可信计算技术