这题其实就是一张无向图,我们要求的就是初始数字’0000’到目标数字target的最短路径,而死亡数组可以看作是图中已经经过的顶点。
单向BFS实现
class Solution {
public int openLock(String[] deadends, String target) {
if("0000".equals(target))return 0;
HashSet<String> visited=new HashSet<>();
for (String deadend:deadends){
visited.add(deadend);
}
if (visited.contains("0000"))return -1;
Deque<String> queue=new ArrayDeque<>();
queue.addLast("0000");
visited.add("0000");
int step=0;
while (!queue.isEmpty()){
int curSize=queue.size();
for (int i=0;i<curSize;i++)
{
String curStr=queue.pollFirst();
if (bfs(curStr,target,queue,visited))return step+1;
}
step++;
}
return -1;
}
public boolean bfs(String cur,String target,Deque<String> queue,HashSet<String> visited)
{
char[] chars=cur.toCharArray();
for (int i=0;i<chars.length;i++)
{
char originCh=chars[i];
chars[i]=(char)(originCh+1);
if (chars[i]>'9')chars[i]='0';
String newStr1=String.valueOf(chars);
if (!visited.contains(newStr1))
{
if (target.equals(newStr1))return true;
queue.addLast(newStr1);
visited.add(newStr1);
}
chars[i]=(char)(originCh-1);
if (chars[i]<'0')chars[i]='9';
String newStr2=String.valueOf(chars);
if (!visited.contains(newStr2))
{
if (target.equals(newStr2))return true;
queue.addLast(newStr2);
visited.add(newStr2);
}
chars[i]=originCh;
}
return false;
}
}
双向BFS实现
class Solution {
public int openLock(String[] deadends, String target) {
if(target.equals("0000"))return 0;
HashSet<String> visited=new HashSet<>();
for (String deadend:deadends)
{
visited.add(deadend);
}
if (visited.contains("0000"))return -1;
HashSet<String> begin=new HashSet<>();
begin.add("0000");
HashSet<String> end=new HashSet<>();
end.add(target);
int step=0;
while (begin.size()!=0&&end.size()!=0)
{
if (begin.size()>end.size())
{
HashSet<String> tmp=begin;
begin=end;
end=tmp;
}
HashSet<String> next=new HashSet<>();
for (String str:begin)
{
if (bfs(str,end,next,visited))return step+1;
}
begin=next;
step++;
}
return -1;
}
public boolean bfs(String cur,HashSet<String> end,HashSet<String> next,HashSet<String> visited){
char[] chars=cur.toCharArray();
for (int i=0;i<chars.length;i++){
char originCh=chars[i];
chars[i]=(char) (originCh+1);
if (chars[i]>'9')chars[i]='0';
String newStr1=String.valueOf(chars);
if (end.contains(newStr1)) return true;
if (!visited.contains(newStr1)) {
visited.add(newStr1);
next.add(newStr1);
}
chars[i]=(char) (originCh-1);
if (chars[i]<'0')chars[i]='9';
String newStr2=String.valueOf(chars);
if (end.contains(newStr2)) return true;
if (!visited.contains(newStr2)) {
visited.add(newStr2);
next.add(newStr2);
}
chars[i]=originCh;
}
return false;
}
}