【双向BFS】LeetCode 752. 打开转盘锁
题目链接
思路
双向BFS,详见宫水三叶大佬题解。
与拓展题目的思路异曲同工。
代码
class Solution {
public int openLock(String[] deadends, String target) {
String beginNumber = "0000";
String endNumber = target;
Set<String> deadNumbers = new HashSet<>(Arrays.asList(deadends));
if(deadNumbers.contains(beginNumber)){
return -1;
}
if(beginNumber.equals(target)){
return 0;
}
return bfs(beginNumber, endNumber, deadNumbers);
}
int bfs(String beginNumber, String endNumber, Set<String> deadNumbers){
Queue<String> queueBegin = new LinkedList<>();
Queue<String> queueEnd = new LinkedList<>();
HashMap<String, Integer> mapBegin = new HashMap<>();
HashMap<String, Integer> mapEnd = new HashMap<>();
queueBegin.offer(beginNumber);
queueEnd.offer(endNumber);
mapBegin.put(beginNumber, 0);
mapEnd.put(endNumber, 0);
int result = -1;
while(!queueBegin.isEmpty() && !queueEnd.isEmpty()){
if(queueBegin.size() < queueEnd.size()){
result = update(queueBegin, mapBegin, mapEnd, deadNumbers);
}else{
result = update(queueEnd, mapEnd, mapBegin, deadNumbers);
}
if(result != -1){
break;
}
}
return result;
}
int update(Queue<String> queue, HashMap<String, Integer> current,
HashMap<String, Integer> other, Set<String> deadNumbers){
int size = queue.size();
while(size > 0){
size--;
String currentNumber = queue.remove();
for(int i = 0; i < currentNumber.length(); i++){
for(int j = -1; j <= 1; j++){
if(j == 0){
continue;
}
int nextInt = (currentNumber.charAt(i) - '0' + j) % 10;
if(nextInt == -1){
nextInt = 9;
}
String nextNumber = currentNumber.substring(0, i) + nextInt + currentNumber.substring(i + 1);
if(!deadNumbers.contains(nextNumber)){
if(current.containsKey(nextNumber) &&
current.get(nextNumber) <= current.get(currentNumber) + 1){
continue;
}
if(other.containsKey(nextNumber)){
return current.get(currentNumber) + 1 + other.get(nextNumber);
}else{
current.put(nextNumber, current.get(currentNumber) + 1);
queue.offer(nextNumber);
}
}
}
}
}
return -1;
}
}