宽度优先搜索BFS

- 搜索方式:一层一层搜索
- 数据结构:队列queue
- 空间:O(2^h^)
- 搜索到的一定是最短路

练习
01 走迷宫

import java.io.*;
import java.util.*;
public class Main {
public static final int N = 110;
public static int[][] g = new int[N][N];
public static int[][] d = new int[N][N];
public static int n, m;
public static class Pair {
public int first;
public int second;
public Pair(int first, int second) {
this.first = first;
this.second = second;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
String[] str1 = br.readLine().split(" ");
n = Integer.parseInt(str1[0]);
m = Integer.parseInt(str1[1]);
for (int i = 0; i < n; i++) {
String[] str2 = br.readLine().split(" ");
for (int j = 0; j < m; j++) {
g[i][j] = Integer.parseInt(str2[j]);
}
}
pw.println(bfs());
br.close();
pw.close();
}
public static int bfs() {
ArrayDeque<Pair> q = new ArrayDeque<>();
for (int i = 0; i < N; i++) {
Arrays.fill(d[i], -1);
}
d[0][0] = 0;
q.offer(new Pair(0, 0));
int[] dx = new int[]{-1, 0, 1, 0};
int[] dy = new int[]{0, 1, 0, -1};
while (q.size() != 0) {
Pair t = q.pop();
for (int i = 0; i < 4; i++) {
int x = t.first + dx[i];
int y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) {
d[x][y] = d[t.first][t.second] + 1;
q.offer(new Pair(x, y));
}
}
}
return d[n - 1][m - 1];
}
}
02 八数码

import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
String[] str1 = br.readLine().split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str1.length; i++) {
sb.append(str1[i]);
}
String start = sb.toString();
pw.println(bfs(start));
br.close();
pw.close();
}
public static int bfs(String start) {
String end = "12345678x";
int[] dx = new int[]{-1, 0, 1, 0};
int[] dy = new int[]{0, 1, 0, -1};
ArrayDeque<String> q = new ArrayDeque<>();
Map<String, Integer> d = new HashMap<>();
q.offer(start);
d.put(start, 0);
while (!q.isEmpty()) {
String t = q.poll();
if (t.equals(end)) {
return d.get(t);
}
int distance = d.get(t);
int k = t.indexOf("x");
int x = k / 3;
int y = k % 3;
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a >= 0 && a < 3 && b >= 0 && b < 3) {
String newState = swapAndToString(t, k, a * 3 + b);
if (!d.containsKey(newState)) {
d.put(newState, distance + 1);
q.offer(newState);
}
}
}
}
return -1;
}
public static String swapAndToString(String t, int a, int b) {
char[] chars = t.toCharArray();
char tmp = chars[a];
chars[a] = chars[b];
chars[b] = tmp;
StringBuilder sb = new StringBuilder();
return sb.append(chars).toString();
}
}
- 题解2
- 使用StringBuffer中的setCharAt方法实现字符串中的两个字符交换,比较新颖,但是比题解1的方式慢一丢丢
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
String[] str1 = br.readLine().split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str1.length; i++) {
sb.append(str1[i]);
}
String start = sb.toString();
pw.println(bfs(start));
br.close();
pw.close();
}
public static int bfs(String start) {
String end = "12345678x";
int[] dx = new int[]{-1, 0, 1, 0};
int[] dy = new int[]{0, 1, 0, -1};
ArrayDeque<String> q = new ArrayDeque<>();
Map<String, Integer> d = new HashMap<>();
q.offer(start);
d.put(start, 0);
while (!q.isEmpty()) {
String t = q.poll();
if (t.equals(end)) {
return d.get(t);
}
int distance = d.get(t);
int k = t.indexOf("x");
int x = k / 3;
int y = k % 3;
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a >= 0 && a < 3 && b >= 0 && b < 3) {
String newState = swap(t, k, a * 3 + b);
if (!d.containsKey(newState)) {
d.put(newState, distance + 1);
q.offer(newState);
}
}
}
}
return -1;
}
public static String swap(String t, int a, int b) {
StringBuffer sb = new StringBuffer(t);
sb.setCharAt(a, t.charAt(b));
sb.setCharAt(b, 'x');
return sb.toString();
}
}