题目
leetcode 752. 打开转盘锁
解法一:单向BFS
class Solution {
public int openLock(String[] deadends, String target) {
int step = 0;
Set<String> deadSet = new HashSet<>();
for (String deadString : deadends)
deadSet.add(deadString);
Set<String> vis = new HashSet<>();
Queue<String> q = new LinkedList<>();
q.offer("0000");
vis.add("0000");
while (!q.isEmpty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
String now = q.poll();
if (now.equals(target))
return step;
if (deadSet.contains(now))
continue;
for (int j = 0; j < 4; j++) {
String up = plus(now, j);
String down = minus(now, j);
if (!vis.contains(up)) {
q.offer(up);
vis.add(up);
}
if (!vis.contains(down)) {
q.offer(down);
vis.add(down);
}
}
}
step++;
}
return -1;
}
private String plus(String str, int pos) {
char[] chars = str.toCharArray();
if (chars[pos] == '9') chars[pos] = '0';
else chars[pos] += 1;
return new String(chars);
}
private String minus(String str, int pos) {
char[] chars = str.toCharArray();
if (chars[pos] == '0') chars[pos] = '9';
else chars[pos] -= 1;
return new String(chars);
}
}
解法二
class Solution {
public int openLock(String[] deadends, String target) {
Set<String> deads = new HashSet<>();
for (String s : deadends) deads.add(s);
Set<String> vis = new HashSet<>();
Set<String> q1 = new HashSet<>();
Set<String> q2 = new HashSet<>();
int step = 0;
q1.add("0000");
q2.add(target);
while (!q1.isEmpty() && !q2.isEmpty()) {
Set<String> tmp = new HashSet<>();
for (String now : q1) {
if (q2.contains(now))
return step;
if (deads.contains(now))
continue;
vis.add(now);
for (int j = 0; j < 4; j++) {
String up = plus(now, j);
if (!vis.contains(up)) tmp.add(up);
String down = minus(now, j);
if (!vis.contains(down)) tmp.add(down);
}
}
step++;
q1 = q2;
q2 = tmp;
}
return -1;
}
private String plus(String str, int pos) {
char[] chars = str.toCharArray();
if (chars[pos] == '9')
chars[pos] = '0';
else
chars[pos] += 1;
return new String(chars);
}
private String minus(String str, int pos) {
char[] chars = str.toCharArray();
if (chars[pos] == '0')
chars[pos] = '9';
else
chars[pos] -= 1;
return new String(chars);
}
}
总结
- 单向BFS从源点出发找目标,最坏情况下遍历整棵树;
- 双向BFS从源点和目标同时出发,交替寻找交集,最坏情况遍历半棵树。