• 力扣:包含重复元素的全排列问题


    给定一个可包含重复数字的序列,返回所有不重复的全排列

    这题与上题的全排列问题类似,问题在于如何将重复序列排除在外。
    这里就需要剪枝思想,即去掉多余的子树。
    我们先看图,令nums=[1,1,2] ![](https://img2020.cnblogs.com/blog/1809280/202004/1809280-20200430115337390-1498940799.png) 图中可以看出,[1]节点与[1]节点一致,当[1`]节点选择子节点时与[1]节点选择时一致,故应该去除。类推。
    再看如何判断剪枝:
    nums[0]=1,nums[1]=1.我们需要将nums[i-1]与nums[i]进行数值判断。同时在nums[i]为父节点进行遍历时,判断nums[i-1]是否已被调用。同时注意边界i>0;
    代码在全排列问题上添加一个剪枝语句。

    public List<List<Integer>> permute(int[] nums) {
            int numsLength = nums.length; // numsLength为nums长度
            List<List<Integer>> res = new ArrayList<>(); // 返回值
            Array.sort(nums); // 排序是剪枝的前提
            Deque<Integer> path = new ArrayDeque<>(); // path类型为Stack类型,系统推荐使用Deque。
                                                        // path用来存放每一次遍历结果
            boolean[] tOf = new boolean[numsLength]; // boolean数组对应nums中数字是否被遍历
            dfs(nums,numsLength,0,path,tOf,res);
            return res;
        }
    
        private void dfs(int[] nums, int numsLength, int depth, Deque<Integer> path, boolean[] tOf, List<List<Integer>> res) {
            // 遍历结束条件
            if (numsLength == depth) {
                res.add(new ArrayList<>(path));
                return;
            }
    
            // for循环遍历
            for (int i = 0; i < numsLength; i++) {
                // 判断nums中数字是否被遍历到
                if (tOf[i]) {
                    continue;
                }
                // 进行剪枝判断
                if (i>0 && nums[i] == nums[i -1] && !tOf[i-1]) {
                    continue;
                }
                // 若未被遍历
                path.addLast(nums[i]); // 将遍历到的nums[i]放入path尾部
                tOf[i] = true; // 将对应tof置为true,表示已遍历
                dfs(nums,numsLength,depth+1,path,tOf,res); // 继续向下搜索
                path.removeLast(); // 假设[1][2][3]回溯,返回上一层[1][2]。但是如何继续返回[1]节点呢
                                    // 这时候tof[1]为true,代表nums[1]已被遍历,继续回撤。
                tOf[i] = false;
            }
        }
    

    有错误或有其他想法的朋友们欢迎评论。

  • 相关阅读:
    微软企业库4.1学习笔记(十一)企业库的核心类 Virus
    微软企业库4.1学习笔记(七)创建对象 续集1 Virus
    微软企业库4.1学习笔记(五)对象创建和依赖注入方法 Virus
    微软企业库4.1学习笔记(十六)缓存模块4 服务器场中的缓存使用 Virus
    Android知识汇总
    移动UI研究学习汇总
    iOS独立存储Demo(调试过可以运行)
    The Official Preppy Handbook 目录
    一个好的App架构应该包括什么?
    转身再不仅仅只是开发人员
  • 原文地址:https://www.cnblogs.com/njuptzheng/p/12807714.html
Copyright © 2020-2023  润新知