回溯算法12-全排列II(Java/排列数去重操作)

12.全排列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]]
  • 题目分析
本题目所描述的全排列存在重复的情况,当nums={1,1,2}时,就会出现两个[1,1,2]的情况,这是由于同一树层,两次添加了1这一相同的元素导致,所以我们需要对树层的元素进行去重操作

image-20240310113946009

1.首先我们将nums数组中的元素进行排序,这样有利于我们将相同的元素同一在一起
2.对于树层上的去重,当我们发下有两个相邻的重复元素时,我们可以进行去重,为了防止类似[1,1]这样的元素被去除,我们可以观察发现
当nums[i] == nums[i - 1] && used[i - 1] == 0时去重可以避免这种情况
解释:在这个条件语句中,首先判断 i 是否大于 0,这是为了避免数组下标越界。然后判断 nums[i] == nums[i - 1],这个条件用来检查当前数字是否与前一个数字相同,也就是判断是否存在重复的数字。最后一个条件 used[i - 1] == 0 则是用来确保前一个相同的数字已经被使用过,如果前一个相同的数字还未被使用,那么当前的排列会和之前的排列重复,因此需要跳过这种情况。

完整代码思路

1.首先,定义了两个全局变量 path 和 result,分别用于存储当前的路径和最终的结果。path 是一个链表,用于暂时存储当前的排列,result 是一个列表,用于存储所有的排列组合。2.然后,定义了一个 permute 方法,接受一个整数数组 nums 作为参数,并返回所有排列的列表。在该方法中,首先初始化了一个长度与 nums 相同的数组 used,用于标记每个数字是否被使用过。然后对 nums 数组进行排序,以确保重复的数字都相邻。接着调用 backtrack 方法开始搜索排列。3.在 backtrack 方法中,首先判断当前的排列长度是否等于 nums 的长度,如果是,则将当前排列加入到 result 中,并返回。接着,使用一个循环遍历 nums 数组中的每个元素,对于每个元素,首先判断是否存在重复的情况,如果存在重复且之前的重复数字未被使用,则跳过当前循环。然后再判断当前元素是否已经被使用过,如果是,则跳过当前循环。如果都不满足,则将当前元素标记为已使用,添加到 path 中,然后递归调用 backtrack 方法继续搜索下一层排列。当递归结束后,将当前元素从 path 中移除,并将其标记为未使用,以便尝试其他可能的排列组合。4.通过这样的回溯过程,最终可以得到所有的排列组合。
  • Java代码实现
LinkedList<Integer> path = new LinkedList<>(); // 用于存储当前路径的链表
List<List<Integer>> result = new ArrayList<>(); // 用于存储最终结果的列表public List<List<Integer>> permute(int[] nums) {int[] used = new int[nums.length]; // 用于标记数字是否被使用过的数组Arrays.sort(nums); // 对输入的数组进行排序,确保相同的数字连续出现backtrack(nums, used, 0); // 调用回溯函数进行全排列return result; // 返回最终结果
}private void backtrack(int[] nums, int[] used, int startIndex) {if (path.size() == nums.length) { // 如果当前路径长度等于数组长度,说明已经找到一个全排列result.add(new ArrayList<>(path)); // 将当前路径添加到结果集中return;}for (int i = 0; i < nums.length; i++) {if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == 0) continue; // 当前数字与前一个数字相等,并且前一个数字未被使用过,则跳过当前循环,避免重复排列if (used[i] == 1) continue; // 如果当前数字已经被使用过,则跳过当前循环used[i] = 1; // 标记当前数字为已使用path.add(nums[i]); // 将当前数字添加到路径中backtrack(nums, used, startIndex + 1); // 递归进入下一层,继续寻找全排列path.removeLast(); // 回溯,将最后一个数字从路径中移除used[i] = 0; // 标记当前数字为未使用,以便后续使用}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot整合zxing实现二维码登录

zxing是google的一个二维码生成库&#xff0c;使用时需配置依赖&#xff1a; implementation("com.google.zxing:core:3.4.1") implementation("com.google.zxing:javase:3.4.1") zxing的基本使用 我们可以通过MultiFormatWriter().encode()方法获取一个…

AI预测福彩3D第3弹【2024年3月6日预测】

书接上回&#xff0c;经过连续两期使用人工神经网络对福彩3D进行预测&#xff0c;经过不断的调参优化&#xff0c;并及时总结规律&#xff0c;感觉还是有一定的信心提高七码的命中概率。 今天&#xff0c;咱们继续来验证&#xff0c;直接上今天的统计结果&#xff0c;首先&…

手写分布式配置中心(五)整合springboot(不自动刷新的)

springboot中使用配置方式有四种&#xff0c;分别是environment、BeanDefinition、Value、ConfigurationProperties。具体的原理可以看我之前的一篇文章https://blog.csdn.net/cjc000/article/details/132800290。代码在https://gitee.com/summer-cat001/config-center 原理 …

斐波那契算法

斐波那契数列 斐波那契数列&#xff08;Fibonacci sequence&#xff09;是一个非常著名的数学序列&#xff0c;它是由意大利数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;在1202年的著作《计算之书》&#xff08;Liber Abaci&#xff09;中首次引入的。这…

SAP 凭证分割功能 - 概述系统配置 - Chapter01/02

目录 1. 概述 2. 系统配置 2.1.为文档拆分给总分类账科目分类 2.2.对凭证拆分的凭证类型进行分类 2.3.定义总账会计核算的凭证分解特征 2.4.定义零余额结算科目 配置步骤: 路径:IMG->财务会计->总帐会计->业务交易->凭证拆分->定义零余额结算科 2.5.定义…

移动端uni-app小程序搜索高亮前端处理,同时可设置相关样式,兼顾性能

在uni-app中我们会遇到搜索高亮显示的需求 如下图&#xff1a; 起初用的是富文本实现 使用replaceAll方法取代搜索字段为一个 标签并设置相应的样式&#xff0c;但是小程序的并没有把 标签渲染出来&#xff0c;所以放弃了&#xff0c;下面原代码&#xff1a; /* 搜索字体变色…

C++进阶:详细讲解继承

现在也是结束了初阶部分的内容&#xff0c;今天开始就进入进阶部分了。一刻也没有为初阶的结束而哀悼&#xff0c;立刻赶来“战场”的是进阶部分里的继承 文章目录 1.继承的概念和定义1.1继承的概念1.2继承的定义1.2.1继承的格式1.2.2再讲访问限定符(详讲protected)1.2.3**继承…

【被c++11弃用的智能指针auto_ptr】

C11标准之前的auto_ptr这个智能指针不被广泛使用的原因就是&#xff1a;在某些应用场景下&#xff0c;拷贝构造函数的意义不明确&#xff0c;同理赋值语句也是这个道理&#xff0c;意义同样不明确&#xff0c;因为C11标准之前并不存在移动赋值和移动构造的概念&#xff0c;还有…

NFT交易市场开发(一)

实现的基本功能 &#xff08;一&#xff09; 发行一个符合ERC20标准的测试Token&#xff0c;要求如下&#xff1a; 总量&#xff1a;&#xff1a;1亿精度&#xff1a;18名称&#xff1a;Fake USDT in CBI简称&#xff1a;cUSDT &#xff08;二&#xff09; 发行一个符合ERC72…

学习方法 学习态度

学习方法 弄清它的历史、局限性和本质 常用的:刻意练习、熟能生巧 不常用的:知道在哪里找就行 事有先后&#xff0c;物有次序&#xff0c;盖房屋必须从平地建起 学习态度 每天比前一天的自己进步一点点

数据结构——算法的空间复杂度

【本节内容】 1.空间复杂度 2.常见空间复杂度 1.空间复杂度 空间复杂度也是一个数学表达式&#xff0c;是对一个算法在运行过程中临时占用额外存储空间大小的量度。 空间复杂度不是程序占用了多少bytes的空间&#xff0c;因为这个也没太大意义&#xff0c;所以空间复杂度算…

random标准模块

一、概述 在 Python 中&#xff0c;random 是一个内置模块&#xff0c;用于生成随机数。它提供了各种用于生成随机数的函数&#xff0c;包括伪随机数生成器、随机序列操作等。 1、需要导包 不会自动导入&#xff0c;需要显示的将random模块导入 import random2、源码分析&…

课时59:流程控制_if条件控制_语法解读

2.2.1 语法解读 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 条件结构能够根据某个特定的条件&#xff0c;结合内置的测试表达式功能&#xff0c;结合测试的结果状态值对于条件进行判断&#xff0c;然后选择执行合适的任务…

Android开发学习-内容共享ContentProvoder(server+client)

在应用之间共享数据 通过ContentProvider封装数据 ContentProvider使用的Uri语法结构如下&#xff1a; content://authority/data_path/id content&#xff1a;通用前缀&#xff0c;表示该uri用于ContentProvider定位资源 authority&#xff1a;是授权者名称&#xff0c;用…

【Greenhills】MULTIIDE集成第三方的编辑器进行源文件编辑工作

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 在使用GHS进行工作的时候&#xff0c;可以集成第三方的编辑器进行源文件编辑工作 2、 问题场景 用于解决在GHS中进行项目开发时&#xff0c;对于GHS的编辑器使用不习惯&#xff0c;想要切换到其他第三方的编辑…

基于c语言的大宗商品撮合交易平台的市场价值

大宗商品撮合交易平台的市场价值主要体现在以下几个方面&#xff1a; 提高市场流动性&#xff1a;平台通过自动化撮合和高效的交易处理&#xff0c;降低了交易成本&#xff0c;提高了市场流动性。这使得投资者能够更容易地找到合适的交易对手&#xff0c;促进交易的成交。 促进…

以题为例 浅谈sql注入布尔盲注

什么是布尔盲注 布尔盲注就是在注入过程中&#xff0c;页面只会返回false和true&#xff0c;不会去返回其它的信息&#xff0c;所以我们不能通过语句查询直接获得数据库的名字&#xff0c;而是通过逻辑获得数据库的信息 布尔盲注常使用函数 length() 返回字符串的长度&#…

TDengine 签约益和热力,应对智慧供热系统大规模数据挑战

近日&#xff0c;涛思数据与安阳益和热力集团有限公司达成合作协议&#xff0c;共同致力于推动智慧供热系统的建设和发展。作为安阳市城市集中供热的主要负责单位&#xff0c;益和热力将借助涛思数据先进的技术和解决方案&#xff0c;提升供热行业的管理效率和服务质量。在本次…

the demo for C# multicast delegate 多播委托

委托类Delegate&#xff0c;位于System命名空间下,是所有声明的委托类型的基类. 例如我们声明了一个委托类型Func<int,bool> MyFunc或者 delegate bool MyDel(int i); 该类型声明成功后&#xff0c;该委托类自动继承System.MulticastDelegate&#xff0c;其包含了构造…

为什么在镀膜时要测薄膜折射率?

在芯片制造中&#xff0c;镀膜工序&#xff08;PVD,CVD&#xff09;是必不可少的关键环节&#xff0c;薄膜的质量直接影响了芯片的性能。对这些薄膜的精细控制又离不开对其折射率的深入理解和精确测量。今天将对芯片制造中薄膜折射率的概念、测量方法&#xff0c;以及它在整个制…