dfs(深度优先搜索)与bfs(宽度/广度优先搜索)
1.dfs(深度优先搜索)
思想:暴力把所有的路径都搜索出来,它运用了回溯,保存这次的位置,深入搜索,都搜索完了便回溯回来,搜下一个位置,直到把所有最深位置都搜一遍,要注意的一点是,搜索的时候有记录走过的位置,标记完后可能要改回来;
回溯法:是一种搜索法,按条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法;
2.bfs(宽度/广度优先搜索)
思想:从某点开始,走四面可以走的路,然后在从这些路,在找可以走的路,直到最先找到符合条件的,这个运用需要用到队列(queue),需要稍微掌握这个才能用bfs。
如题:
题目(长草)
【问题描述】
小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。
小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。
请告诉小明,k 个月后空地上哪些地方有草。
【输入格式】
输入的第一行包含两个整数 n, m。
接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
接下来包含一个整数 k。
【输出格式】
输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。
【样例输入】
4 5
.g…
…
…g…
…
2
【样例输出】
gggg.
gggg.
ggggg
.ggg.
【评测用例规模与约定】
对于 30% 的评测用例,2 <= n, m <= 20。
对于 70% 的评测用例,2 <= n, m <= 100。
对于所有评测用例,2 <= n, m <= 1000,1 <= k <= 1000。
考试时我的代码(未使用bfs):
public class Eight {
//最大达到10的9次方,超时
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
String[][] di = new String[n][m];
for (int i = 0; i < n; i++) {
String str = in.next();
for (int j = 0; j < m; j++) {
di[i][j] = String.valueOf(str.charAt(j));
}
}
int k = in.nextInt();
long now = System.currentTimeMillis();
for (int i = 0; i < k; i++) {
di = zhang(di);
}
for (int i = 0; i < di.length; i++) {
for (int j = 0; j < di[0].length; j++) {
System.out.print(di[i][j]);
}
System.out.println();
}
System.err.println(System.currentTimeMillis()-now);
}
public static String[][] zhang(String di[][]) {
String[][] result = new String[di.length][di[0].length];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[0].length; j++) {
if (di[i][j].equals("g")) {
result[i][j] = "g";
} else {
result[i][j] = ".";
}
}
}
for (int i = 0; i < di.length; i++) {
for (int j = 0; j < di[0].length; j++) {
if (di[i][j].equals("g")) {
if (i >= 1) { // 向上长
result[i - 1][j] = "g";
}
if (i <= di.length-2) {
result[i + 1][j] = "g";
}
if (j >= 1) {
result[i][j - 1] = "g";
}
if (j <= di[0].length-2) {
result[i][j + 1] = "g";
}
}
}
}
return result;
}
答案代码(运用了bfs):
// 答案方法,最大10的6次方,不超时
static final int[] dx = {1, 0, -1, 0};
static final int[] dy = {0, 1, 0, -1};
static Scanner sc ;
static int[][] vis = new int[1000][1000];
static int N, M, K;
public static void main(String[] args) throws IOException {
sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
sc.nextLine();
LinkedList<Block> q = new LinkedList<Block>();
for (int i = 0; i < N; i++) {
String line = sc.nextLine();
for (int j = 0; j < M; j++) {
if (line.charAt(j) == 'g') {
q.addLast(new Block(i, j, 0));
vis[i][j] = 1;
}
}
}
K = sc.nextInt();
long now = System.currentTimeMillis();
while (!q.isEmpty()) {
Block b = q.removeFirst();
int month = b.month;
if (month < K) {
for (int i = 0; i <= 3; i++) {
int nx = b.i + dx[i];
int ny = b.j + dy[i];
if (0 <= nx && nx < N && 0 <= ny && ny < M && vis[nx][ny] == 0) {
vis[nx][ny] = 1;
q.addLast(new Block(nx, ny, month + 1));
}
}
}
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (vis[i][j] == 1) writer.write('g');
else writer.write('.');
}
writer.write('\n');
}
writer.flush();
System.err.println(System.currentTimeMillis()-now);
}
//草地上的一块
private static class Block {//只能有一个公共类,因此这里使用private或不写
int i;
int j;
int month;
public Block(int i, int j, int month) {//因为类没有参数,所以需要在类中再写一个方法给Block的属性赋值
this.i = i;
this.j = j;
this.month = month;
}
}
3.dfs和bfs的区别
bfs是用来搜索最短径路的解法是比较合适的
比如求最少步数的解,最少交换次数的解,最快走出迷宫等等,因为bfs搜索过程中遇到的第一个解一定是离最初位置最近的,所以遇到第一个解,一定就是最优解,此时搜索算法可以终止
bfs是浪费空间节省时间,dfs是浪费时间节省空间。
因为dfs要走很多的路径,可能都是没用的,(做有些题目的时候要进行剪枝,就是确定不符合条件的就可以结束,以免浪费时间,否则有些题目会TLE);
而bfs可以走的点要存起来,需要队列,因此需要空间来储存,便是浪费了空间,假设有十层,各个结点有2个子节点,那么储存到第10层就要存 2^10-1 个数据,而dfs只需要存10个数据,但是找到答案的速度相对快一点。
上一篇: 搭建K8s集群
推荐阅读
-
python深度优先搜索和广度优先搜索
-
DFS(一):深度优先搜索的基本思想
-
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
-
210课程表 II(拓扑排序广度优先搜索、深度优先搜索——困难)
-
可能是目前为止最为详细的深度优先搜索DFS和广度优先搜索BFS算法分析
-
数据结构与算法-----BFS与DFS(广度优先搜索与深度优先搜索)
-
数据结构与算法_深度优先搜索(DFS)与广度优先搜索(BFS)详解
-
Java数据结构与算法:图、图的概念、深度优先搜索DFS、广度优先搜索BFS、思路分析、代码实现
-
【数据结构】图的遍历——深度优先搜索DFS、广度优先搜索BFS
-
Java数据结构与算法——深度优先搜索与广度优先搜索