可以把这题看成一个以“0000”为中心,向外辐射八个节点的图
每辐射一次就是一层
就可以使用BFS算法了
这里还有一个超时的注意要点,已经在注释中标出
class Solution {
//该位向上拨一下
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);
}
//该位向下拨一下
String minusOne(String s,int j){
char[] ch = s.toCharArray();
if(ch[j] == '0'){
ch[j] = '9';
}else{
ch[j] -= 1;
}
return new String(ch);
}
public int openLock(String[] deadends, String target) {
Queue<String> q = new LinkedList<>();
Set<String> visited = new HashSet<>();
Set<String> dead = new HashSet<>();
for(String s:deadends){
dead.add(s);
}
int step = 0;
q.offer("0000");
visited.add("0000");
while(!q.isEmpty()){
int sz = q.size();
//每一层
for(int i = 0;i<sz;i++){
//一层中的其中一个
String cur = q.poll();
//每一个节点走到才标记一次,会超时,因此要在下面的辐射时标记
// visited.add(cur);
//找到了
if(cur.equals(target)){
return step;
}
//找错路了,不能以这个点继续辐射
if(dead.contains(cur)){
continue;
}
//辐射的8个新点,归到下一层
for(int j = 0;j<4;j++){
String up = plusOne(cur,j);
if(!visited.contains(up)){
q.offer(up);
//解决超时问题
visited.add(up);
}
String down = minusOne(cur,j);
if(!visited.contains(down)){
q.offer(down);
//解决超时问题
visited.add(down);
}
}
}
step++;
}
return -1;
}
}
双向BFS
class Solution {
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);
}
String minusOne(String s,int j){
char[] ch = s.toCharArray();
if(ch[j] == '0'){
ch[j] = '9';
}else{
ch[j] -= 1;
}
return new String(ch);
}
public int openLock(String[] deadends, String target) {
Set<String> deads = new HashSet<>();
for(String s : deadends){
deads.add(s);
}
Set<String> q1 = new HashSet<>();
Set<String> q2 = new HashSet<>();
Set<String> visited = new HashSet<>();
int step = 0;
q1.add("0000");
q2.add(target);
while(!q1.isEmpty() && !q2.isEmpty()){
Set<String> temp = new HashSet<>();
for(String cur : q1){
if(deads.contains(cur)){
continue;
}
if(q2.contains(cur)){
return step;
}
visited.add(cur);
for(int j = 0;j < 4;j++){
String up = plusOne(cur,j);
if(!visited.contains(up)){
temp.add(up);
}
String down = minusOne(cur,j);
if(!visited.contains(down)){
temp.add(down);
}
}
}
step++;
q1 = q2;
q2 = temp;
}
return -1;
}
}