[英]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.