BFS算法解决FloodFill问题
图像渲染

题目解析 :就是将这里面指定一个元素将其上下左右和这个一样的值,全部修改成另外一个值,并且其上下左右也可以进行上下左右进行扩展,也就是将这个一片区域都修改成color指定值
BFS:直接遍历所有下标,并且看其上下左右下标,不断进行修改,不断进行扩展延申
此时就可以使用队列放入 int 数组,对应存放行、列下标,每一次不断取出进行上下左右延申判断其是否和imagesrsc,如果一样就继续放入队列中,不断进行操作,直到队列为空

这里通过上下左右对应下标分别

java
class Solution {
int[] dx = {0,0,1,-1};
int[] dy = {1,-1,0,0};
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
int prev = image[sr][sc];
if(prev == color){
//如果要修改和修改的一样,此时就不需要修改
return image;
}
int m = image.length;
int n = image[0].length;
//存放其下标
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{sr,sc});
while(!queue.isEmpty()){
int[] tem = queue.poll();
int a = tem[0];//行
int b = tem[1];//列
//将这个颜色修改
image[a][b] = color;
//看这个位置前后左右位置
for(int i = 0;i < 4;i++){
int x = a + dx[i];
int y = b + dy[i];
if(x >=0 && x < m && y>=0 && y < n && image[x][y] == prev){
queue.add(new int[]{x,y});
}
}
}
return image;
}
}
岛屿数量

题目解析 :此时1表示岛屿,并且1的上下左右如果有1的话就会进行延申展开,最终求出有多少岛屿
BFS:遍历整个数组,但是此时一个岛屿需要延申到不能延申为止这样才成为一个岛屿 ,此时会出现问题,我们会不断扩展,后面遍历到这个位置又会让其岛屿数量+1,此时就重复统计了,这里有两种解决方案
方案一 :每次遍历过的位置,将这里的 1 修改成 0
方案二:创建一个同等规模的数组,如果统计过了就进行标记一下

java
class Solution {
int[] dx = {0,0,1,-1};
int[] dy = {1,-1,0,0};
boolean[][] visited;//标记已经遍历过的位置
int m = 0;
int n = 0;
public int numIslands(char[][] grid) {
m = grid.length;
n = grid[0].length;
visited = new boolean[m][n];
int ret = 0;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
//当时1并且没有遍历过,结果++
if(grid[i][j] == '1' && visited[i][j] == false){
ret++;
dfs(grid,i,j);//将其旁边的visited都标记为遍历过
}
}
}
return ret;
}
public void dfs(char[][] grid,int i,int j){
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{i,j});
visited[i][j] = false;
while(!queue.isEmpty()){
int[] tem = queue.poll();
int a = tem[0];
int b = tem[1];
for(int k = 0; k < 4;k++){
int x = a + dx[k];
int y = b + dy[k];
if(x >= 0 && x < m && y >= 0&&y < n&&grid[x][y] == '1' && !visited[x][y]){
queue.add(new int[]{x,y});
visited[x][y] = true;
}
}
}
}
}
岛屿的最大面积

题目解析 :就是找出岛屿最大面积
思想:此时和上一题岛屿数量类似,此时我们只需要在dfs方法中返回此时岛屿数量即可

java
class Solution {
int[] dx = { 0, 0, 1, -1 };
int[] dy = { 1, -1, 0, 0 };
boolean[][] visited;//标记已经遍历过的
int m = 0;
int n = 0;
public int maxAreaOfIsland(int[][] grid) {
int ret = 0;
m = grid.length;
n = grid[0].length;
visited = new boolean[m][n];
//此时遍历这个岛屿的时候统计一下它的面积,返回
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1 && visited[i][j] == false) {
//此时更新结果
ret = Math.max(ret, dfs(grid, i, j));
}
}
}
return ret;
}
public int dfs(int[][] grid,int i,int j){
int count = 0;//此时岛屿面积
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{i,j});
visited[i][j] = true;
count++;
while(!queue.isEmpty()){
//队列为空就结束
int[] tem = queue.poll();
int a = tem[0];
int b = tem[1];
for(int k = 0;k<4;k++){
int x = a + dx[k];
int y = b + dy[k];
//延申
if(x >= 0&&x < m && y >= 0 && y < n &&grid[x][y] == 1 && visited[x][y] == false){
queue.add(new int[]{x,y});
visited[x][y] = true;
count++;
}
}
}
return count;
}
}
被围住的区域

题目解析 :就是将被X围住的O修改成X,未被围住的不做修改
思想:由于以前是一边遍历,一边修,但是这里会出现不需要修改的问题,可能修改一半发现不需要修改,此时这里还需要进行二次判断因此这里采用正难则反的思想
1.先使用dfs遍历边界,此时将边界及其扩展部分修改成 其他字符
2.最后遍历一遍数组,将剩下未被修改的O修改成X,将这里被修改成其他字符的修改回以前的O字符

java
class Solution {
int[] dx = { 0, 0, 1, -1 };
int[] dy = { 1, -1, 0, 0 };
int m = 0;
int n = 0;
public void solve(char[][] board) {
m = board.length;
n = board[0].length;
//1.将边界的O以及相邻的O全部修改成 . 最后在修改回来
//左右两列
for (int i = 0; i < m; i++) {
if (board[i][0] == 'O') {
dfs(board, i, 0);
}
if (board[i][n - 1] == 'O') {
dfs(board, i, n - 1);
}
}
//上下两行
for (int i = 0; i < n; i++) {
if (board[0][i] == 'O') {
dfs(board, 0, i);
}
if (board[m - 1][i] == 'O') {
dfs(board, m - 1, i);
}
}
//剩下的O修改成X,将上面修改的还原
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') {
board[i][j] = 'X';
//修改回来
} else if (board[i][j] == '.') {
board[i][j] = 'O';
}
}
}
}
public void dfs(char[][] board, int i, int j) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[] { i, j });
board[i][j] = '.';//修改成.
while (!queue.isEmpty()) {
int[] tem = queue.poll();
int a = tem[0];
int b = tem[1];
for (int k = 0; k < 4; k++) {
int x = a + dx[k];
int y = b + dy[k];
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') {
queue.add(new int[] { x, y });
board[x][y] = '.';
}
}
}
}
}