广度优先搜索

Posted 浮云神码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了广度优先搜索相关的知识,希望对你有一定的参考价值。

    今天最好再分享两个广度优先搜索的题目,从明天开始分享深度优先搜索。


import java.util.LinkedList;import java.util.Queue;
/** * https://leetcode-cn.com/problems/surrounded-regions * 130. 被围绕的区域 * 难度 中等 * 给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域, * 并将这些区域里所有的'O' 用 'X' 填充。 * * 示例 1: * * * 输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] * 输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] * 解释:被围绕的区间不会存在于边界上,换句话说,任何边界上的'O'都不会被填充为'X'。 * 任何不在边界上,或不与边界上的'O'相连的'O'最终都会被填充为'X'。 * 如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。 * 示例 2: * * 输入:board = [["X"]] * 输出:[["X"]] * * 提示: * * m == board.length * n == board[i].length * 1 <= m, n <= 200 * board[i][j] 为 'X' 或 'O' * * 来源:力扣(LeetCode) * 链接:https://leetcode-cn.com/problems/surrounded-regions */public class SurroundedRegions {
public void solve(char[][] board) {
Queue<Index> queue = new LinkedList<>(); // 获取数组的行列数 int m = board.length; int n = board[0].length;
/** * 初始化四条边上的'O', 基于 任何边界上的'O'都不会被填充为'X' */ for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { // 判断矩阵的四条边上是否有'O' if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { if (board[i][j] == 'O') { queue.add(new Index(i, j)); // 使用A替代O, 做标识, 说明此位置没有被X包围 board[i][j] = 'A'; } } } }
while (!queue.isEmpty()) { Index index = queue.remove(); handleAdjacentData(board, index.i, index.j - 1, queue); // 上 handleAdjacentData(board, index.i, index.j + 1, queue); // 下 handleAdjacentData(board, index.i - 1, index.j, queue); // 左 handleAdjacentData(board, index.i + 1, index.j, queue); // 右 }
// 遍历矩阵, 将'A'改为'O', 其他字符改为'X' for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (board[i][j] == 'A') { board[i][j] = 'O'; } else { board[i][j] = 'X'; } } } }
public void handleAdjacentData(char[][] board, int i, int j, Queue<Index> queue) { // i, j 不必再判断矩阵四条边 if (i > 0 && i < board.length - 1 && j > 0 && j < board[0].length - 1) { if (board[i][j] == 'O') { queue.add(new Index(i, j)); board[i][j] = 'A'; } } }}
class Index { public int i;
public int j;
public Index(int i, int j) { this.i = i; this.j = j; }}


import java.util.LinkedList;import java.util.Queue;
/** * https://leetcode-cn.com/problems/number-of-islands * 200. 岛屿数量 * 难度 中等 * 给你一个由'1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 * * 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 * * 此外,你可以假设该网格的四条边均被水包围。 * * 示例 1: * * 输入:grid = [ * ["1","1","1","1","0"], * ["1","1","0","1","0"], * ["1","1","0","0","0"], * ["0","0","0","0","0"] * ] * 输出:1 * 示例 2: * * 输入:grid = [ * ["1","1","0","0","0"], * ["1","1","0","0","0"], * ["0","0","1","0","0"], * ["0","0","0","1","1"] * ] * 输出:3 * * 提示: * * m == grid.length * n == grid[i].length * 1 <= m, n <= 300 * grid[i][j] 的值为 '0' 或 '1' * * 来源:力扣(LeetCode) * 链接:https://leetcode-cn.com/problems/number-of-islands */public class NumberOfIslands { public int numIslands(char[][] grid) { int result = 0; int m = grid.length; int n = grid[0].length;
Queue<Index> queue = new LinkedList<>(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { // 找到一块被包围的岛屿 result++; // 将相连的岛全部找到 queue.add(new Index(i, j)); grid[i][j] = 'A'; changeSearchedIsland(grid, queue); } } } return result; }
/** * 将所有相连的岛屿 标志置为A * @param grid * @param queue */ private void changeSearchedIsland(char[][] grid, Queue<Index> queue) { while (!queue.isEmpty()) { Index current = queue.remove(); // 上 if (current.i - 1 >= 0 && grid[current.i - 1][current.j] == '1') { grid[current.i - 1][current.j] = 'A'; queue.add(new Index(current.i - 1, current.j)); } // 下 if (current.i + 1 < grid.length && grid[current.i + 1][current.j] == '1') { grid[current.i + 1][current.j] = 'A'; queue.add(new Index(current.i + 1, current.j)); } // 左 if (current.j - 1 >= 0 && grid[current.i][current.j - 1] == '1') { grid[current.i][current.j - 1] = 'A'; queue.add(new Index(current.i, current.j - 1)); } // 右 if (current.j + 1 < grid[0].length && grid[current.i][current.j + 1] == '1') { grid[current.i][current.j + 1] = 'A'; queue.add(new Index(current.i, current.j + 1)); } } }
class Index { public int i;
public int j;
public Index(int i, int j) { this.i = i; this.j = j; } }}


以上是关于广度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章

Prolog中的广度优先搜索

面试题算法: 广度优先搜索

图相关算法

图解:深度优先搜索与广度优先搜索

广度优先搜索遍历图

无向图 广度优先搜索 和 深度优先搜索