【搜索】bfs 和 dfs 的模板

dfs

dfs 递归模板

dfs 的思想就像是二叉树的先序遍历。

public void solve(char[][] grid) {
  for (int i = 0; i < m; i++) 
  for (int j = 0; j < n; j++) {
    if (grid[i][j] == ?)
      dfs(grid, i, j);
  }
}
void dfs(char[][] grid, int i, int j) {
  if (判边界 || 额外条件) {
     return;
  }
  
  具体额外的操作...
  
  dfs(grid, i - 1, j); // 上
  dfs(grid, i + 1, j); // 下
  dfs(grid, i, j - 1); // 左
  dfs(grid, i, j + 1); // 右

  某些操作的回溯...
}

dfs 非递归模板

非递归 dfs 一般用 stack,一般用非递归都需要一种辅助类 Pos 来记录结点的横纵坐标,甚至可能需要增加其他状态遍历记录某个结点的价值。

//主方法
public int solve(char[][] grid) {
  for (int i = 0; i < m; i++) 
  for (int j = 0; j < n; j++) {
    if (grid[i][j] == ?)
      dfs(grid, i, j);
  }
}
//深搜
void dfs(char[][] grid, int i, int j) {
    stack.push(new Pos(i, j));
    
    额外操作...
    
    while( !stack.isEmpty() ) {
      ...
      stack.peek();
      int u, d, l, r;       // 上、下、左、右
	  if(u >= 0 && 附加条件) {
        stack.push(new Pos(u, currPos.j));
        continue;
      }
      ...
      stack.pop();
    }
}

bfs

bfs 非递归

dfs 和 dfs 不同的是,dfs 中搜索 u, d, l, r,只要搜索到一个满足条件,dfs 就顺着该方向继续搜索,所以你可以看到 dfs 代码中,只要满足条件,就入 Stack,然后 continue 本次搜索,进行下一次搜索。

bfs 中,我们要把上下左右满足条件的都入队,所以搜索的时候就不能 continue。

public void solve(char[][] grid) {
  for (int i = 0; i < m; i++) 
  for (int j = 0; j < n; j++) {
    if (grid[i][j] == ?)
      bfs(grid, i, j);
  }
}
void bfs(char[][] grid, int i, int j) {
  queue.add(new Pos(i, j));
  while (!queue.isEmpty()) {
 	Pos pos = queue.poll();
 	for (int k = 0; k < 4; k++) {	//搜索四个方向合适的结点
	  if (判边界 && grid[newX][newY] == 1)
	    queue.add(new Pos(newX, newY, pos.minute + 1)); 
	}
  }
}

练手题目

发布了461 篇原创文章 · 获赞 102 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104657591