BFS就是宽度优先遍历,通过一个队列来实现BFS
1.图像渲染

算法讲解:BFS,通过一个队列来实现
代码实现:
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 h=image.length;
int l=image[0].length;
int prev=image[sr][sc];
Queue<int[]> q = new LinkedList<>();
if(image[sr][sc]==color) return image;
q.offer(new int[]{sr,sc});
image[sr][sc]=color;
while(!q.isEmpty()){
int[] index = q.poll();
int i=index[0];
int j=index[1];
for(int k=0;k<4;k++){
int x=i+dx[k];
int y=j+dy[k];
if(x>=0 && x<h && y>=0 && y<l && image[x][y]==prev){
image[x][y]=color;
q.offer(new int[]{x,y});
}
}
}
return image;
}
}
2.岛屿数量

算法讲解:这道题主要是用一个同等规模的boolean类型的数组去记录已经访问过的位置,还有一个细节就是:在有多次的bfs时,尽量不要将Queue弄成全局,这样会让每次的bfs用的是同一个队列,此时可能队列中会有上一次bfs的残留,会影响到下一次的bfs,尽量让每次的bfs的队列都是一个新的队列。
代码实现:
java
class Solution {
int[] dx={0,0,-1,1};
int[] dy={-1,1,0,0};
boolean[][] check;
int h,l,ret;
public int numIslands(char[][] grid) {
h=grid.length;
l=grid[0].length;
check=new boolean[h][l];
for(int i=0;i<h;i++){
for(int j=0;j<l;j++){
if(grid[i][j]=='1'&&check[i][j]==false){
ret++;
bfs(grid,i,j);
}
}
}
return ret;
}
public void bfs(char[][] grid,int a,int b){
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{a,b});
check[a][b]=true;
while(!q.isEmpty()){
int[] index = q.poll();
int i=index[0];
int j=index[1];
for(int k=0;k<4;k++){
int x=i+dx[k];
int y=j+dy[k];
if(x>=0 && x<h && y>=0 && y<l && grid[x][y]=='1' && check[x][y]==false){
q.offer(new int[]{x,y});
check[x][y]=true;
}
}
}
}
}
3.岛屿的最大面积
题目链接:695. 岛屿的最大面积 - 力扣(LeetCode)

这道题和上一道题的思路一模一样
代码实现:
java
class Solution {
int[] dx={0,0,-1,1};
int[] dy={-1,1,0,0};
boolean[][] check;
int h,l;
public int maxAreaOfIsland(int[][] grid) {
int ret=0;
h=grid.length;
l=grid[0].length;
check=new boolean[h][l];
for(int i=0;i<h;i++){
for(int j=0;j<l;j++){
if(grid[i][j]==1&&check[i][j]==false){
ret=Math.max(ret,bfs(grid,i,j));
}
}
}
return ret;
}
public int bfs(int[][] grid,int a,int b){
int ret=1;
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{a,b});
check[a][b]=true;
while(!q.isEmpty()){
int[] index = q.poll();
int i=index[0];
int j=index[1];
for(int k=0;k<4;k++){
int x=i+dx[k];
int y=j+dy[k];
if(x>=0 && x<h && y>=0 && y<l && grid[x][y]==1 && check[x][y]==false){
ret++;
q.offer(new int[]{x,y});
check[x][y]=true;
}
}
}
return ret;
}
}
4.被围绕的区域
题目链接:130. 被围绕的区域 - 力扣(LeetCode)

算法讲解:正难则反,我们可以先去处理边界的情况,先将位于边界的连通O区域全部改为字符点,处理完边界情况之后,在去遍历矩阵,遇到字符点,则就将其还原成O,此时如果遇到O,那么此时的O区域肯定是合法的,此时直接将O改为X即可
代码实现
java
class Solution {
int[] dx={0,0,-1,1};
int[] dy={-1,1,0,0};
int h,l;
public void solve(char[][] board) {
h=board.length;
l=board[0].length;
for(int j=0;j<l;j++){
if(board[0][j]=='O') bfs(board,0,j);
if(board[h-1][j]=='O') bfs(board,h-1,j);
}
for(int i=0;i<h;i++){
if(board[i][0]=='O') bfs(board,i,0);
if(board[i][l-1]=='O') bfs(board,i,l-1);
}
for(int i=0;i<h;i++){
for(int j=0;j<l;j++){
if(board[i][j]=='.') board[i][j]='O';
else if(board[i][j]=='O') board[i][j]='X';
}
}
}
public void bfs(char[][] board,int a,int b){
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{a,b});
board[a][b]='.';
while(!q.isEmpty()){
int[] index = q.poll();
int i=index[0];
int j=index[1];
for(int k=0;k<4;k++){
int x=i+dx[k];
int y=j+dy[k];
if(x>=0 && x<h && y>=0 && y<l && board[x][y]=='O'){
board[x][y]='.';
q.offer(new int[]{x,y});
}
}
}
}
}