打开转盘锁
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 91 ms, 内存: 16.7 MB
/*
* 思路:
* 1. 使用广度优先搜索(BFS)算法来解决这个问题。
* 2. 从起始状态 "0000" 开始,通过每次旋转拨轮生成新的状态。
* 3. 使用一个队列来存储当前状态和步数。
* 4. 使用一个集合来存储死亡数字和已访问的状态,避免重复访问。
* 5. 如果当前状态是目标状态,返回步数。
* 6. 如果遍历完所有可能的状态仍未找到目标状态,返回 -1。
* 7. 使用Java Stream来简化代码。
*/
import java.util.*;
import java.util.stream.*;
public class OpenLockStream {
public int openLock(String[] deadends, String target) {
Set<String> dead = Arrays.stream(deadends).collect(Collectors.toSet());
Set<String> visited = new HashSet<>();
Queue<String> queue = new LinkedList<>();
queue.offer("0000");
visited.add("0000");
int steps = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String current = queue.poll();
if (dead.contains(current)) {
continue;
}
if (current.equals(target)) {
return steps;
}
getNextStates(current).stream()
.filter(next -> !visited.contains(next))
.forEach(next -> {
queue.offer(next);
visited.add(next);
});
}
steps++;
}
return -1;
}
private List<String> getNextStates(String state) {
return IntStream.range(0, 4).boxed()
.flatMap(i -> Stream.of(
new StringBuilder(state).replace(i, i + 1, String.valueOf((state.charAt(i) - '0' + 1) % 10)).toString(),
new StringBuilder(state).replace(i, i + 1, String.valueOf((state.charAt(i) - '0' + 9) % 10)).toString()
))
.collect(Collectors.toList());
}
public static void main(String[] args) {
OpenLockStream solution = new OpenLockStream();
String[] deadends = {"0201", "0101", "0102", "1212", "2002"};
String target = "0202";
System.out.println(solution.openLock(deadends, target)); // 输出: 6
}
}
解释
方法:
本题解采用了双向广度优先搜索(BFS)算法。首先将起始点'0000'和目标点target分别加入到两个集合q1和q2中。算法交替从q1和q2中的一个较小的集合扩展,以此达到双向搜索的目的。每一步都检查当前节点是否出现在对方集合中,如果出现,表示找到了最短路径。如果没有,就将当前节点的所有相邻节点(通过拨动锁一位得到)添加到临时集合中,然后将q1和q2交换,继续下一轮搜索。搜索过程中会跳过出现在deadends集合中的节点。
时间复杂度:
O(N)
空间复杂度:
O(N)
代码细节讲解
🦆
在双向BFS中,为何选择始终扩展较小的集合来提高效率?这样做的数学或算法基础是什么?
▷🦆
为了避免死锁,算法在遇到deadends中的节点时选择跳过。如果初始状态'0000'就在deadends中,算法是否有处理这种情况的机制?
▷🦆
在双向BFS的实现中,如何确保在两个队列都非空的条件下仍然能有效检测到路径的交点?
▷