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;
    }
}
相关推荐
凤山老林24 分钟前
授权模型只会RBAC?深入 ABAC 授权模型,实现权限判断做成策略引擎
大数据·数据库·算法
海绵宝宝转agent1 小时前
2026-10-21学习笔记
笔记·学习·算法
Dxy12393102161 小时前
ShardingSphere 自定义分片算法:BINARY(16) UUIDv7 哈希分片实现
算法·哈希算法
y1su1 小时前
Leetcode 链表,树,回溯 模板
java·leetcode·链表
罗湖老棍子12 小时前
【例 1】Sightseeing Trip(信息学奥赛一本通- P1494)(洛谷-P10927)
数据结构·算法·图论·最短路·floyd·最小环
文丑颜不良啊13 小时前
LeetCode201~225题目解析
java·leetcode
stsdddd15 小时前
YOLO算法建筑工地安全帽目标检测数据集16881张:标注核对笔记
算法·yolo·目标检测
CV爱数码15 小时前
论文精读|Learned Primal-Dual:把原始–对偶算法展开成网络
图像处理·算法·计算机视觉·ct·重建·断层扫描
yuniko-n16 小时前
【算法】约瑟夫环问题
java·算法
l1t16 小时前
测试DuckDB v2.1.0-alpha49002的bignum乘法
数据库·sql·算法·duckdb