广度优先搜索
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;
}
}
}
以上是关于广度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章