[英]Shortest Path(s) in unweighted 2D array. How to show steps/directions taken during BFS
[英]How to print out the path taken by the BFS?
我正在解决 Leetcode 中的一个问题,我们给出了一个锁组合,可以从 0000 的起始组合到达。您一次只能旋转一个锁轮,并且必须尽可能少转动。 我有我的解决方案来做到这一点,它工作正常,但我不知道如何实际打印出 BFS 到达该解决方案所采用的路径(即用于到达它的中间组合)。 任何帮助,将不胜感激!
class Solution {
private static final String START = "0000";
public int openLock(String[] deadends, String target) {
if (target == null || target.length() == 0) return -1;
Set<String> visited = new HashSet<>(Arrays.asList(deadends));
Queue<String> queue = new LinkedList<>();
int level = 0;
queue.offer(START);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String currentLock = queue.poll();
if (!visited.add(currentLock)) continue;
if (currentLock.equals(target)) return level;
for (String nextLock : getNextStates(currentLock)) {
if (!visited.contains(nextLock)) queue.offer(nextLock);
}
}
level++;
}
return -1;
}
private List<String> getNextStates(String lock) {
List<String> locks = new LinkedList<>();
char[] arr = lock.toCharArray();
for (int i = 0; i < arr.length; i++) {
char c = arr[i];
arr[i] = c == '9' ? '0' : (char) (c + ((char) 1));
locks.add(String.valueOf(arr));
arr[i] = c == '0' ? '9' : (char) (c - ((char) 1));
locks.add(String.valueOf(arr));
arr[i] = c;
}
return locks;
}
}
我认为你可以通过维持孩子父母的关系来实现它。
Map<String,String> childToParent = new HashMap<String,String>();
String currentLock = null;
boolean found = false;
while (!queue.isEmpty() && !found) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String currentLock = queue.poll();
if (!visited.add(currentLock)) continue;
if (currentLock.equals(target)){
found = true;
break;
}
for (String nextLock : getNextStates(currentLock)) {
if (!visited.contains(nextLock)){
queue.offer(nextLock);
childToParent.put(nextLock,currentLock);
}
}
}
level++;
}
if(!found){
return -1;
}
// Printing path
int level = 0;
while(childToParent.get(currentLock) != null){
System.out.println(currentLock);
currentLock = childToParent.get(currentLock);
level++;
}
System.out.println(currentLock);
return level;
就像@Tarun 说的,你可以保持孩子与父母的关系。 我使用了一种更好的方法,但首先我要谈谈您遇到的其他问题。 第一个是你这样做: Set<String> visited = new HashSet<>(Arrays.asList(deadends));
Arrays.asList(...)
在你的情况下应该接受deadends
中的每个String
。 所以,你应该把它改成这样:
HashSet<String> set = new HashSet<>();
for(String s : deadends) {
set.add(s);
}
当然,将其重命名为visited
,我只是从我接受的解决方案中复制和粘贴内容。 此外,您使用Queue
的方式并没有错,但是如果您一次从中取出所有内容然后填充新值,不妨使用LinkedList
或ArrayList
。 您应该从Queue
一一接收条目,然后Queue
放置较新的条目,因此您不必担心跳过某些内容。
跟踪您所做的移动量的更好方法是将其存储到Queue
本身中。 您存储当前组合和到达那里所采取的步骤数量。 因此,当您找到答案时,只需返回第二个条目,即步数。 如果跳出循环,则返回 -1。 这是我接受的所有解决方案:
class Solution {
public int openLock(String[] deadends, String target) {
HashSet<String> set = new HashSet<>();
for(String s : deadends) {
set.add(s);
}
HashSet<String> visited = new HashSet<>();
Queue<Pair<String, Integer>> queue = new LinkedList<>();
queue.offer(new Pair<>("0000", 0));
while(!queue.isEmpty()) {
Pair<String, Integer> curr = queue.poll();
if(set.contains(curr.first) || !visited.add(curr.first)) {
continue;
} else if(curr.first.equals(target)) {
return curr.second;
} else {
LinkedList<String> next = next(curr.first);
for(String s : next) {
queue.offer(new Pair<>(s, curr.second + 1));
}
}
}
return -1;
}
private LinkedList<String> next(String string) {
LinkedList<String> ans = new LinkedList<>();
ans.add(String.valueOf(new char[]{minus(string.charAt(0)), string.charAt(1), string.charAt(2), string.charAt(3)}));
ans.add(String.valueOf(new char[]{plus(string.charAt(0)), string.charAt(1), string.charAt(2), string.charAt(3)}));
ans.add(String.valueOf(new char[]{string.charAt(0), minus(string.charAt(1)), string.charAt(2), string.charAt(3)}));
ans.add(String.valueOf(new char[]{string.charAt(0), plus(string.charAt(1)), string.charAt(2), string.charAt(3)}));
ans.add(String.valueOf(new char[]{string.charAt(0), string.charAt(1), minus(string.charAt(2)), string.charAt(3)}));
ans.add(String.valueOf(new char[]{string.charAt(0), string.charAt(1), plus(string.charAt(2)), string.charAt(3)}));
ans.add(String.valueOf(new char[]{string.charAt(0), string.charAt(1), string.charAt(2), minus(string.charAt(3))}));
ans.add(String.valueOf(new char[]{string.charAt(0), string.charAt(1), string.charAt(2), plus(string.charAt(3))}));
return ans;
}
private char minus(char c) {
return c == '0' ? '9' : (char) ((int) c - 1);
}
private char plus(char c) {
return c == '9' ? '0' : (char) ((int) c + 1);
}
private class Pair<E, T> {
E first;
T second;
Pair(E e, T t) {
first = e;
second = t;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.