打开轮盘锁问题(LeetCode)的分析总结及进一步提问
打开轮盘锁问题分析总结,及进一步提问:请给出一组最小步数下的号码序列组合
题目描述
你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’ 。每次旋转都只能旋转一个拨轮的一位数字。
锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串。
列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。
进一步提问:请给出一组最小旋转次数下的号码序列组合
题目示例
示例1:
输入:deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
输出:6
解释:
可能的移动序列为 “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”。
注意 “0000” -> “0001” -> “0002” -> “0102” -> “0202” 这样的序列是不能解锁的,
因为当拨动到 “0102” 时这个锁就会被锁定。
示例2:
输入: deadends = [“8888”], target = “0009”
输出:1
解释:把最后一位反向旋转一次即可 “0000” -> “0009”。
示例3:
输入: deadends = [“8887”,“8889”,“8878”,“8898”,“8788”,“8988”,“7888”,“9888”], target = “8888”
输出:-1
解释:无法旋转到目标数字且不被锁定。
求解
解决这个问题的一个常用方法是使用广度优先搜索(BFS)。广度优先搜索适合用于寻找最短路径的问题。在这种情况下,我们可以将每个可能的状态视为图中的一个节点,相邻状态视为图中的边。通过 BFS,我们可以找到从初始状态 “0000” 到目标状态的最短路径,同时避免所有的死亡数字状态。
要找出最少步数的密码状态组合,可以在广度优先搜索(BFS)过程中记录路径。在找到目标状态时,我们可以回溯路径来确定最少步数的密码状态组合。
详细步骤
1.初始化:
- 使用一个队列来进行 BFS,初始状态为 “0000”。
- 使用一个集合存储死亡数字,以便快速查找。
- 使用一个集合存储已访问的状态,以避免重复访问。
- 使用一个 Map 记录每个状态的前驱状态,以便在找到目标状态时回溯路径。
2.BFS 过程:
- 每次从队列中取出一个状态,检查它是否是目标状态。
- 对于当前状态的每一个位置,可以尝试增加或减少一位数字,生成新的状态。
- 如果生成的状态不是死亡数字且未被访问过,将其加入队列、已访问集合,并记录前驱状态。
- 继续这个过程,直到找到目标状态或者队列为空。
3.路径回溯:
- 当找到目标状态时,从目标状态开始,通过 Map 回溯到初始状态,生成路径。
代码实现
/*** 根据记录的密码序列父子关系,回溯所有密码序列* @param deadends 一组死亡数字* @param target 最末端的密码序列* @return 正序的密码序列数据(包括“0000”根节点)。* 当列表size不为0时,size-1 即为最小步数;* 当列表size为0时,表示:无论如何不能解锁。*/
public List<String> openLock(String[] deadends, String target) {Set<String> deadSet = new HashSet<>(Arrays.asList(deadends));if (deadSet.contains("0000")) {return Collections.emptyList();}//队列,实现BFS广度优先遍历Queue<String> queue = new LinkedList<>();//记录当前密码序列的上一个密码序列,即:记录父节点关系,便于回溯所有密码序列。Map<String, String> parent = new HashMap<>();//记录已经设置过的密码序列,防止重复判断陷入无限循环。Set<String> visited = new HashSet<>();queue.offer("0000");visited.add("0000");parent.put("0000", null);//根节点的父节点设置为空int steps = 0;while (!queue.isEmpty()) {int size = queue.size();//遍历每一层节点for (int i = 0; i < size; i++) {String current = queue.poll();if (current.equals(target)) {//最小步数产生,即最短路径或最小深度,回溯路径return constructPath(parent, target);}//根据当前密码序列,计算产生新的密码序列for (String next : getNextStates(current)) {if (!visited.contains(next) && !deadSet.contains(next)) {queue.offer(next);visited.add(next);parent.put(next, current);//记录父节点}}}steps++; //记录步数}return Collections.emptyList();
}/*** 根据记录的密码序列父子关系,回溯所有密码序列* @param parent 父子序列关系Map* @param target 最末端的密码序列* @return 正序的密码序列数据(包括“0000”根节点)*/
private List<String> constructPath(Map<String, String> parent, String target) {List<String> path = new LinkedList<>();for (String at = target; at != null; at = parent.get(at)) {path.add(at);}Collections.reverse(path);return path;
}/*** 获取当前密码序列的下一个状态的所有序列数据* @param current 当前密码序列* @return 所有的下一个状态序列*/
private List<String> getNextStates(String current) {List<String> nextStates = new ArrayList<>();char[] chars = current.toCharArray();for (int i = 0; i < 4; i++) {char original = chars[i];// 向前拨动密码轮盘chars[i] = original == '9' ? '0' : (char) (original + 1);nextStates.add(new String(chars));// 向后拨动密码轮盘chars[i] = original == '0' ? '9' : (char) (original - 1);nextStates.add(new String(chars));// 回复原来的号码chars[i] = original;}return nextStates;
}
测试代码
String[] deadends = {"0201", "0101", "0102", "1212", "2002"};String target = "0202";
// String[] deadends = {"8887", "8889", "8878", "8898", "8788", "8988","7888","9888"};
// String target = "8888";
// String[] deadends = {"8888"};
// String target = "0009";List<String> path = openLock(deadends, target);if (path.isEmpty()) {System.out.println("无论如何不能解锁!");} else {System.out.println("解锁序列:");for (String state : path) {System.out.println(state);}}
相关文章:

打开轮盘锁问题(LeetCode)的分析总结及进一步提问
打开轮盘锁问题分析总结,及进一步提问:请给出一组最小步数下的号码序列组合 题目描述 你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由…...

python——joblib进行缓存记忆化-对计算结果缓存
问题场景 在前端多选框需要选取多个数据进行后端计算。 传入后端是多个数据包的对应路径。 这些数据包需要按一定顺序运行,通过一个Bag(path).get_start_time() 可以获得一个float时间值进行排序,但由于数据包的特性,这一操作很占用性能和时…...

Linux文件管理
系列文章目录 提示:仅用于个人学习,进行查漏补缺。 1.Linux介绍、目录结构、文件基本属性、Shell 2.Linux常用命令 3.Linux文件管理 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1…...

《Unity3D网络游戏实战》学习与实践--制作一款大乱斗游戏
角色类 基类Base Human是基础的角色类,它处理“操控角色”和“同步角色”的一些共有功能;CtrlHuman类代表“操控角色”,它在BaseHuman类的基础上处理鼠标操控功能;SyncHuman类是“同步角色”类,它也继承自BaseHuman&…...
文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑源-荷不确定性的省间电力现货市场潮流风险概率评估》
本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…...

Pinterest 选择采用 TiDB
原文来源: https://tidb.net/blog/9f000c95 作者:Pinterest 公司高级软件工程师 Alberto Ordonez Pereira ;高级工程经理 Lianghong Xu 声明:本文转载于 https://medium.com/pinterest-engineering/tidb-adoption-…...

【Python】 如何用 Docker 打包一个 Python 脚本
这是我父亲 日记里的文字 这是他的生命 留下留下来的散文诗 几十年后 我看着泪流不止 可我的父亲已经 老得像一个影子 🎵 许飞《父亲写的散文诗》 如何用 Docker 打包一个 Python 脚本 Docker 是一个开源的容器化平台,允许开发者将…...

从“幕后”到“台前”:一文读懂API经济如何促进企业的创新与增长
API(Application Programming Interface,应用程序接口)指一组定义软件程序如何与其他组件、服务或系统交互的规范。在传统的IT语境中,API往往更多承担前后端对接或应用系统间内部集成渠道的作用。但在当今大数据与智能化的时代&am…...

解锁PDF新姿势:2024年PDF转图片工具精选
随着数字化办公的普及和文档处理需求的日益增长,PDF转图片工具已成为日常工作中不可或缺的一部分。这些工具不仅帮助用户轻松地将PDF文件转换为图片格式,还提供了丰富的编辑、转换和批量处理功能,极大地提高了工作效率。 1.福昕PDF转换大师&…...

Node.js(8)——Express的基本使用
监听GET请求 通过app.get()方法,可以监听客户端GET请求,具体语法: app.get(请求URL,function(req,res){处理函数}) 监听POST请求 语法: app.post(请求URL,function(req,res){处理函数}) 把内容响应给客户端 通过res.send()方法…...

Linux--应用层协议HTTP
HTTP协议 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,它基于TCP/IP通信协议来传送数据,规定了浏览器与服务器之间数据传输的规则,确保数据能够在网络源头…...

Flux:Midjourney的新图像模型挑战者
--->更多内容,请移步“鲁班秘笈”!!<--- Black Forest Labs是一家由前Stability.ai开发人员创立的AI初创公司,旨在为图像和视频创建尖端的生成式 AI 模型。这家初创公司声称,其第一个模型系列Flux.1为文本到图像…...

RabbitMQ高级特性 - 消费者消息确认机制
文章目录 RabbitMQ 消息确认机制背景消费者消息确认机制概述手动确认(RabbitMQ 原生 SDK)手动确认(Spring-AMQP 封装 RabbitMQ SDK)AcknowledgeMode.NONEAcknowledgeMode.AUTO(默认)AcknowledgeMode.MANUAL…...

PermX-htb
0x01 立足 信息收集 端口扫描 nmap -sSCV -Pn 10.10.11.23 正常开启22和80端口 访问web页面 并没有看到有攻击点 这个页面可先记录一会儿有需要的话可以尝试xss获取cookie 域名扫描 ffuf -w 1.txt -u http://permx.htb/ -H Host:FUZZ.permx.htb 这里用的ffuf扫描工具 扫出了…...

解密RCE漏洞:原理剖析、复现与代码审计实战
在网络安全领域,远程代码执行(RCE)漏洞因其严重性和破坏力而备受关注。RCE漏洞允许攻击者在目标系统上执行任意代码,从而掌控整个系统,带来极大的安全风险。理解RCE漏洞的工作原理,并掌握其复现与代码审计技…...

打造智能家居:用React、Node.js和WebSocket构建ESP32设备控制面板(代码说明)
一、项目概述 在物联网(IoT)时代,智能设备的远程控制变得越来越重要。本文介绍了一个构建智能设备控制面板的项目,允许用户通过 Web 应用来控制多个 ESP32 设备。用户可以通过该面板查看设备列表,实时了解设备状态&am…...

计网:从输入URL到网页显示期间发生了什么
1、URL包含的信息 我们输入的url中包含着一些信息: http:表示的此次我们使用的什么协议/www.baidu.com:表示的是我们想要访问的服务器名称,也就是域名dir3/home.html:表示我们所要访问的资源 2、通过DNS解析URL获得I…...

龚宇引以为傲的“爆款制造营”,爱奇艺怕是要爽约了
文:互联网江湖 作者:刘致呈 人们经常用人红戏不红,来形容毯星,综艺上咋咋呼呼,一提都知道,可问及代表作,不好意思,这个真没有。 今年的爱奇艺,貌似也迎来了这一宿命。 …...

org.springframework.web.client.HttpClientErrorException$NotFound异常
springCloud报错信息:org.springframework.web.client.HttpClientErrorException$NotFound: 404 null第一点: 第二点:没有httpclient工具类 注入RestTmeplate类时,改类需要RestController或ResponseBody...

在开关电源转换器中充分利用碳化硅器件的性能优势
在过去的几十年中,半导体行业已经采取了许多措施来改善基于硅 MOSFET (parasitic parameters),以满足开关转换器(开关电源)设计人员的需求。行业效率標準以及市场对效率技术需求的双重作用,导致了对于可用于构建更高效…...

QObject::connect: Cannot queue arguments of type ‘QList<QString>‘
QObject::connect: Cannot queue arguments of type ‘QList’ QObject::connect: Cannot queue arguments of type QList<QString> (Make sure QList<QString> is registered using qRegisterMetaType().)使用信号和槽时,QList无法当做参数被传递&…...

基于K8S部署安装Jenkins
基于K8S部署安装Jenkins 1.Jenkins Kubernetes 清单文件2.Kubernetes Jenkins 部署1:为 Jenkins 创建 Namespace。 最好将所有DevOps工具分类为与其他应用程序分开的命名空间。2:创建“serviceAccount.yaml”文件并复制以下管理员服务帐户清单。1. kubec…...

24-8-4-读书笔记(十三)-《莎士比亚全集》(第一卷(续)) [英] 威廉·莎士比亚 [译]朱生豪
文章目录 《莎士比亚全集》(第一卷(续))目录阅读笔记记录总结《莎士比亚全集》(第一卷(续)) 《莎士比亚全集》朱生豪的经典译本,非常值得花时间去读一读,莎氏的巨作有其独特的韵味,与莫里哀、契诃夫、曹禺等其他国家的剧作家有其鲜明的特点,这既是源于其所处的时代…...

linux nicstat
nicstat 是一个用于监控和报告网络接口统计信息的工具。它可以提供关于网络接口的详细性能数据,包括传输速率、错误率、丢包率等。nicstat 对于诊断网络性能问题和优化网络配置非常有用。 安装 nicstat nicstat 可能不在所有Linux发行版的默认软件库中,…...

程序员如何积累人脉?光靠技术不行了~
从事技术的人,还没被社会“塑造”前,总会有一个“固有思维”,就是这个世界大概率是“由代码和逻辑主宰的世界”,人脉积累并不在考虑范围内,而我们也常被误解为只懂得与机器对话的technician。 事实上,游戏…...

初识增强现实(AR)
初识增强现实(AR) 笔记来源: 1.2023年中国增强现实(AR)行业研究报告 2.wiki/Augmented reality 3.In-Depth Review of Augmented Reality: Tracking Technologies, Development Tools, AR Displays, Collaborative AR…...

开关电源起振是什么看了就知道
接触开关电源的朋友都知道,含有电源管理芯片的开关电源有输入,没输出时常说是不是电路没起振,到底这句话是什么意思呢?什么是“起振”先不做 的解释,简单打个比方,大家就容易懂了,就好像抢救心…...

Modbus_Ascii协议
设备必须要有RTU协议!这是Modbus协议上规定的,且默认模式必须是RTU,ASCII作为选项。(也就是说,一般的设备只有RTU这个协议,ASCII一般很少)所以说,一般学习Modbus协议,只需…...

树莓派在功能和成本之间的 “惊人平衡 “支持了全球数字标牌的成功故事!
树莓派的“功能和成本之间的惊人平衡”支撑全球数字标牌成功故事 数字标牌已经成为一个数十亿美元的行业。Yodeck很快预测到了其中的潜力:他们需要硬件来支持他们可靠、具有成本效益和易于管理的服务,而不会影响性能。事实证明,树莓派 4 证明…...

C++ 学习记录
文章目录 继承重载和重写区别重载重写 参考文献 继承 继承顾名思义就是对长辈本有的东西进行获取与使用,即两个以及两个类以上的关系在获取与使用时会存在一些情况: public:长辈对外公开的自身所有物,最终都会是后代的protected&…...