当前位置:网站首页>Force buckle, 752-open turntable lock
Force buckle, 752-open turntable lock
2022-08-02 01:54:00 【star and dawn】
This question is medium,But I think it's still very difficult,Learned from my brother,Just a little bit of sharing.
你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字
: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ .
每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’ .
And each spin can only spin one digit of the dial.
锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串.
列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转.
字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 .
输入:deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
输出:6
解释:
可能的移动序列为 “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”.
注意 “0000” -> “0001” -> “0002” -> “0102” -> “0202” 这样的序列是不能解锁的,
因为当拨动到 “0102” 时这个锁就会被锁定
输入: deadends = [“8888”], target = “0009”
输出:1
解释:把最后一位反向旋转一次即可 “0000” -> “0009”.
输入: deadends = [“8887”,“8889”,“8878”,“8898”,“8788”,“8988”,“7888”,“9888”], target = “8888”
输出:-1
解释:无法旋转到目标数字且不被锁定.
This question can be used typically BFS 算法,广度优先遍历算法.
To use the idea of breadth-first traversal algorithm.总结一下:
First traverse to enumerate all password combinations,Of course, exhaustion also requires certain laws of symbols to exhaustively.
比如:,从“0000”开始,转一次,会出现“1000”、“9000”、“0100”、“0900”、“0010”、“0090”、“0001”、“0009”这样共8种情况.Then to the next time,再以这 8 password-based,Do it again for each password,Just list all the situations.To take into account when exhaustive,It is possible to go back.
比如:从“0000”走到“1000”,But right next time“1000”when exhausted,会出现“0000”,This will cause an infinite loop.按照题目的要求,判断到达 target 就可以结束,and returns the last recorded number of toggles.
也要对 deadends This dead code is handled,That is to say, in this case, this judgment should be skipped.
不多逼逼,看代码,There are more detailed instructions in the code:
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
public class Demo752 {
public static void main(String[] args) {
String[] str = {
"8887", "8889", "8878", "8898", "8788", "8988", "7888", "9888"};
String target = "8888";
System.out.println(openLock(str, target));
}
public static int openLock(String[] deadends, String target) {
// Save dead codes that need to be skipped
Set<String> strings = new HashSet<>();
for (String deadend : deadends) {
strings.add(deadend);
}
// Record all passwords that have been exhausted,防止回头路
Set<String> visited = new HashSet<>();
Queue<String> queue = new LinkedList<>();
//Start performing a breadth-first search
int step = 0;
queue.offer("0000");
visited.add("0000");
while (!queue.isEmpty()) {
int sz = queue.size();
for (int i = 0; i < sz; i++) {
String str = queue.poll();
//Determine whether the current password is qualified,Unqualified skip directly
if (strings.contains(str)) {
continue;
}
// The password reaches the end,返回路径长度
if (str.equals(target)) {
return step;
}
// Qualified but unfinished nodes are added to the queue by traversing adjacent nodes
// 使用4is because the string length is 4
for (int j = 0; j < 4; j++) {
//Get data up
String up = plusOne(str, j);
if (!visited.contains(up)) {
queue.offer(up);
visited.add(up);
}
//Get data down
String down = minusOne(str, j);
if (!visited.contains(down)) {
queue.offer(down);
visited.add(down);
}
}
}
step++;
}
// If exhausted,没有结果,就返回-1
return -1;
}
//Will be the first of the number currently givenjShift one bit up
public static String plusOne(String s, int j) {
char[] ch = s.toCharArray();
if (ch[j] == '9') {
ch[j] = '0';
} else {
ch[j] += 1;
}
return new String(ch);
}
//Will be the first of the number currently givenjShift down one digit
public static String minusOne(String str, int j) {
char[] ch = str.toCharArray();
if (ch[j] == '0') {
ch[j] = '9';
} else {
ch[j] -= 1;
}
return new String(ch);
}
}
The above code is fully reflected,广度优先遍历,Start from one point and expand outward step by step.
On this subject again,We can use bidirectional here too BFS.
传统的 BFS The algorithm starts from the starting point and continues to spread around,It will stop until it reaches the end.
而双向 BFS The algorithm is to start spreading from the start and end points at the same time,当两边有交集的时候停止.
These two ideas actually follow Big O notation to analyze,It has both worst complexity O(N),But in fact it goes both ways BFS It will still be chunky,双向 BFS In fact, it only needs to traverse half of the number and the result will appear.
不过双向 BFS There is also a necessary restriction.It has to know where the end point is.
代码演示,There are also slight notes:
public static int openLock(String[] deadends, String target) {
// Save dead codes that need to be skipped
Set<String> strings = new HashSet<>();
for (String deadend : deadends) {
strings.add(deadend);
}
// Record all passwords that have been exhausted,防止回头路
Set<String> visited = new HashSet<>();
Set<String> queue1 = new HashSet<>();
Set<String> queue2 = new HashSet<>();
//Start performing a breadth-first search
int step = 0;
queue1.add("0000");
queue2.add(target);
while (!queue1.isEmpty() && !queue2.isEmpty()) {
// It cannot be modified during the traversal process hash 表的
// 用 temp 存储 queue1 the result of the diffusion,作为中间数
Set<String> temp = new HashSet<>();
// 将 queue1 中的所有节点向周围扩散
for (String str : queue1) {
//Determine whether the current password is qualified,Unqualified skip directly
if (strings.contains(str)) {
continue;
}
// The password reaches the end,返回路径长度
if (queue2.contains(str)) {
return step;
}
visited.add(str);
// Qualified but unfinished nodes are added to the queue by traversing adjacent nodes
// 使用4is because the string length is 4
for (int j = 0; j < 4; j++) {
//Get data up
String up = plusOne(str, j);
if (!visited.contains(up)) {
temp.add(up);
}
//Get data down
String down = minusOne(str, j);
if (!visited.contains(down)) {
temp.add(down);
}
}
}
step++;
//翻转
queue1 = queue2;
queue2 = temp;
}
// If exhausted,没有结果,就返回-1
return -1;
}
边栏推荐
- For effective automated testing, these software testing tools must be collected!!!
- ¶Backtop 回到顶部 不生效
- 【服务器数据恢复】服务器Raid5阵列mdisk磁盘离线的数据恢复案例
- 数据链路层的数据传输
- TKU记一次单点QPS优化(顺祝ITEYE终于回来了)
- The characteristics and principle of typescript29 - enumeration type
- 密码学的基础:X.690和对应的BER CER DER编码
- 求大神解答,这种 sql 应该怎么写?
- 记录一次数组转集合出现错误的坑点,尽量使用包装类型数组进行转换
- 6-25 Vulnerability Exploitation - irc Backdoor Exploitation
猜你喜欢

hash table

传统企业数字化转型需要经过几个阶段?

typeof in typescript32-ts

【ORB_SLAM2】void Frame::ComputeImageBounds(const cv::Mat &imLeft)

Can‘t connect to MySQL server on ‘localhost3306‘ (10061) 简洁明了的解决方法

typescript30 - any type

typescript36-class的构造函数实例方法

Reflex WMS中阶系列7:已经完成拣货尚未Load的HD如果要取消拣货,该如何处理?

【Brush the title】Family robbery

创新项目实战之智能跟随机器人原理与代码实现
随机推荐
去经营企业吧
『网易实习』周记(一)
typescript29-枚举类型的特点和原理
TKU记一次单点QPS优化(顺祝ITEYE终于回来了)
C语言之插入字符简单练习
Image fusion based on weighted 】 and pyramid image fusion with matlab code
5年自动化测试经验的一些感悟:做UI自动化一定要跨过这10个坑
搜罗汇总的效应
HSDC is related to Independent Spanning Tree
LeetCode刷题日记:153、寻找旋转排序数组中的最小值
60种特征工程操作:使用自定义聚合函数【收藏】
Kubernetes — 网络流量模型
雇用WordPress开发人员:4个实用的方法
Navicat数据显示不完全的解决方法
Byte taught me a hard lesson: When a crisis comes, you don't even have time to prepare...
27英寸横置大屏+实体按键,全新探险者才是安全而合理的做法!
kubernetes之服务发现
安全(2)
PHP直播源码实现简单弹幕效果的相关代码
密码学的基础:X.690和对应的BER CER DER编码