聊聊leetcode可包含重复数字的序列的《47. 全排列 II》中的vis标记函数

news/2024/7/20 20:56:30 标签: leetcode, 深度优先, 算法, 全排列

1 题目描述(字节二面题目)

在这里插入图片描述

2 代码

class Solution {
    List<List<Integer>>res;
    List<Integer>list;
    boolean[]used;
    public List<List<Integer>> permuteUnique(int[] nums) {
        res=new ArrayList<>();
        list=new ArrayList<>();
        used=new boolean[nums.length];
        Arrays.sort(nums);
        dfs(nums,0);
        return res;
    }

    
    void dfs(int[]nums,int s){
        if(list.size()==nums.length){
            res.add(new ArrayList<>(list));
            return;
        }
        
        for(int i=0;i<nums.length;i++){
            if(used[i]||(i>0&&nums[i]==nums[i-1]&&!used[i-1])){ // #A
                continue;
            }
            list.add(nums[i]);
            used[i]=true;
            dfs(nums,i);
            list.remove(list.size()-1);
            used[i]=false;

        }
    }
}

3 关于2中的#A处代码的解析

这是一行关于剪枝的判断语句,具体有两个重要的判断条件(used[i]||(i>0&&nums[i]==nums[i-1]&&!used[i-1])),满足其中任一个都可以跳过当前元素的遍历,我们都知道第一条件是用于判断向下遍历时,当前准备选取的元素是否已经在路径中,如果used[i]==true,则跳过;第二个条件是用于去重判断,我们在dfs函数运行之前对数组进行了排序,在横向遍历的时候需要进行去重(i>0&&nums[i]==nums[i-1]),但是我们得确定怎么样算是横向遍历,关键就是!used[i-1]这个代码,我们都知道dfs函数会对used[i-1]进行回溯,当我们横向遍历到第i个元素时,则used[0…(i-1)]都必然是false才能满足横向遍历的判断。

3.1 那这个!used[i-1]可以去掉吗?

当然不能,因为只有带上这个,i>0&&nums[i]==nums[i-1]才会仅仅在横向判断的时候起作用,如果不带这个,那么这个去重代码还会在纵向遍历的时候起作用。

以nums=[1,1,2]为例,如果dfs函数的#A行带上,那么输出[[1,1,2],[1,2,1],[2,1,1]],如果去掉#A行的!used[i-1],则返回[]

为什么后者会导致输出为空列表呢?
答:去掉!used[i-1],导致去重操作也发生在了纵向遍历的过程中,当遍历到第二个1时,used[0]为true或者false都不重要,都会因为i>0&&nums[i]==nums[i-1]的判断导致被剪枝。


http://www.niftyadmin.cn/n/5177895.html

相关文章

高并发架构设计(三大利器:缓存、限流和降级)

引言 高并发背景 互联网行业迅速发展&#xff0c;用户量剧增&#xff0c;系统面临巨大的并发请求压力。 软件系统有三个追求&#xff1a;高性能、高并发、高可用&#xff0c;俗称三高。三者既有区别也有联系&#xff0c;门门道道很多&#xff0c;全面讨论需要三天三夜&#…

一行JavaScrip可以做什么?

说在前面 JavaScript 提供了许多方便的方法和操作符来简化常见的任务&#xff0c;使得编程变得更加高效和便捷。无论是数学计算、字符串处理还是数据操作&#xff0c;JavaScript 都能帮助我们以简洁的方式实现所需功能。 代码 1、生成指定范围内的随机整数 const randomInt …

HarmonyOS开发(二):TypeScript入门

1、编程语言介绍 ArkTS是HarmonyOS主推的应用开发语言&#xff0c;它是在TypeScript语言的基础之上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 ArkTS、TypeScript和JavaScript之间…

无监督学习的集成方法:相似性矩阵的聚类

在机器学习中&#xff0c;术语Ensemble指的是并行组合多个模型&#xff0c;这个想法是利用群体的智慧&#xff0c;在给出的最终答案上形成更好的共识。 这种类型的方法已经在监督学习领域得到了广泛的研究和应用&#xff0c;特别是在分类问题上&#xff0c;像RandomForest这样…

CTFhub-RCE-evel执行

访问目标地址&#xff1a; <?php if (isset($_REQUEST[cmd])) { eval($_REQUEST["cmd"]); } else { highlight_file(__FILE__); } ?> 根据PHP代码显示&#xff0c;要求将命令赋值给cmd然后执行 先查看一下根目录文件 /?cmdsystem("ls")…

Linux命令——netstat

netstat 命令用于显示各种网络相关信息&#xff0c;如网络连接&#xff0c;路由表&#xff0c;接口状态 (Interface Statistics)&#xff0c;masquerade 连接&#xff0c;多播成员 (Multicast Memberships) 等等。 从整体上看&#xff0c;netstat的输出结果可以分为两个部分&a…

OpenCV+相机校准和3D重建

相机校准至少需要10个测试图案&#xff0c;所需的重要输入数据是3D现实世界点集以及图像中这些点的相应2D坐标。3D点称为对象点&#xff0c;而2D图像点称为图像点。 准备工作 除了棋盘&#xff0c;我们还可以使用圆形网格。 在这种情况下&#xff0c;我们必须使用函数cv.find…

伦敦银为什么降价

作为贵金属家族中的一员&#xff0c;白银具有一定的金融属性&#xff0c;但它同时也是一种工业金属&#xff0c;在太阳能、汽车、电子工业上有着广泛的用途&#xff0c;所以其价格会受到诸多因素的影响。伦敦银作为紧密跟着国际现货白银价格走势的品种&#xff0c;其降价的原因…