
752 打开转盘锁(宽搜)
发布日期:2021-05-07 21:50:06
浏览次数:19
分类:精选文章
本文共 3036 字,大约阅读时间需要 10 分钟。
为了解决这个问题,我们需要找到从初始状态"0000"到目标状态的最短旋转次数,同时避开死亡数字列表中的状态。我们可以使用广度优先搜索(BFS)来解决这个问题,因为BFS能够找到最短路径。
方法思路
问题分析:我们需要从初始状态"0000"出发,每次只能旋转一个拨轮到目标状态。每个拨轮可以旋转10次,数字可以循环(如9旋转一次变成0,0旋转一次变成9)。如果在旋转过程中到达任何一个死亡状态,锁就会被永久锁定,无法继续旋转。
算法选择:使用广度优先搜索(BFS)来找到从初始状态到目标状态的最短路径。BFS适合这种问题,因为它能逐层扩展,找到最短路径。
状态表示:每个状态是一个四位字符串,表示四个拨轮的当前数字。每次旋转一个拨轮,生成新的状态。
避免重复访问:使用集合来记录已经访问过的状态,避免重复处理。
死亡状态检查:在生成每个新状态时,检查它是否在死亡状态列表中。如果是,跳过这个状态。
解决代码
import java.util.*;public class Solution { Setvisited = new HashSet<>(); Queue queue = new LinkedList<>(); public int openLock(String[] deadends, String target) { // 预处理:如果初始状态在死锁列表中,直接返回-1 for (String s : deadends) { if ("0000".equals(s)) { return -1; } } // 预处理死锁列表为集合,提高查询效率 Set deadSet = new HashSet<>(); for (String s : deadends) { deadSet.add(s); } // 初始化队列和已访问集合 visited.add("0000"); queue.add(new Node("0000", 0, "0000")); while (!queue.isEmpty()) { Node current = queue.poll(); if (current.cur.equals(target)) { return current.step; } // 生成所有可能的下一步状态 String[] nextStates = generateNextStates(current.cur); for (String state : nextStates) { if (!visited.contains(state)) { // 检查是否是死锁状态 if (!deadSet.contains(state)) { visited.add(state); queue.add(new Node(state, current.step + 1, current.road + "-->" + state)); } } } } return -1; } // 生成所有可能的下一步状态 private String[] generateNextStates(String cur) { List nextStates = new ArrayList<>(); for (int i = 0; i < 4; i++) { char c = cur.charAt(i); int num = c - '0'; // 加1的情况 int nextAdd = num + 1; if (nextAdd > 9) { nextAdd = 0; } String addState = cur.substring(0, i) + nextAdd + cur.substring(i + 1); nextStates.add(addState); // 减1的情况 int nextSub = num - 1; if (nextSub < 0) { nextSub = 9; } String subState = cur.substring(0, i) + nextSub + cur.substring(i + 1); nextStates.add(subState); } return nextStates.toArray(new String[0]); } // 节点内部类 static class Node { String cur; int step; String road; Node(String cur, int step, String road) { this.cur = cur; this.step = step; this.road = road; } }}
代码解释
预处理:检查初始状态是否在死亡状态列表中,若是,直接返回-1。将死亡状态列表转换为集合,提高查询效率。
BFS初始化:将初始状态"0000"加入队列,并标记为已访问。
处理队列:每次从队列中取出当前状态,生成所有可能的下一步状态。
生成下一步状态:对于每个位,生成加1和减1两种情况,生成新的状态字符串。
状态检查:检查新状态是否在死亡状态列表中,若不在且未被访问过,将其加入队列。
目标状态检查:如果当前状态是目标状态,返回当前步数。
通过这种方法,我们可以找到从初始状态到目标状态的最短旋转次数,或者返回-1表示无法解锁。
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年03月28日 01时30分06秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
C语言指针收藏
2019-03-06
.net 4种单例模式
2019-03-06
T4 生成数据库实体类
2019-03-06
C#搞个跨平台的桌面NES游戏模拟器
2019-03-06
手把手教你安装Eclipse最新版本的详细教程 (非常详细,非常实用)
2019-03-06
《带你装B,带你飞》pytest成魔之路4 - fixture 之大解剖
2019-03-06
互联网App应用程序测试流程及测试总结
2019-03-06
根据轨迹分析出用户家在哪
2019-03-06
PostgreSQL查询表名称及表结构
2019-03-06
是什么?评估分类器的常用概念----准确率,精确率,召回率
2019-03-06
linux中使用awk命令
2019-03-06
LAB2 内核的内存管理
2019-03-06
如何使用google搜索?
2019-03-06
Redis分布式锁的正确实现方式
2019-03-06
设计模式-抽象工厂模式
2019-03-06
MySQL Explain查看执行计划详解
2019-03-06
IntelliJ IDEA 中,项目文件右键菜单没有svn选项解决办法
2019-03-06
Spring 动态绑定多实现类实例综述
2019-03-06
IDEA 调试Java代码的两个技巧
2019-03-06
MyBatis常见面试题:#{}和${}的区别是什么?
2019-03-06