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.lengthn == board[i].length1 <= m, n <= 200board[i][j]为'X'或'O'
题解
这题看起来好像下棋,只要把对方围起来之后就把对面的吃掉。我们需要把被围起来的圈圈全部换成叉叉。那什么是被围起来,看题目给的数据,只要连通的圈圈不在边边上的,那都是被圈起来了。那怎么知道不在边边上,那就是扩展时,如果继续扩展节点超过了边界,那这个圈圈就在边界上。所以通过广搜或深搜进行扩展,只要扩展不到边边上的,都换为叉叉。
主要步骤:
-
广搜圈圈,看看是否扩展到边界
- 扩展到边界,不用置为叉叉
- 没有扩展到边界,置为叉叉
class Solution {
int[] dx = {1, -1, 0, 0};//上下左右移动
int[] dy = {0, 0, 1, -1};//上下左右移动
public void solve(char[][] board) {
int r = board.length;//行长度
int c = board[0].length;//列长度
Queue<int[]> queue = new LinkedList<int[]>();//广度搜索辅助队列
boolean[][] visit = new boolean[r][c];//访问数组
for(int i = 0; i < r; i++){//遍历行
for(int j = 0; j < c; j++){//遍历列
if(!visit[i][j] && board[i][j] == 'O'){//没有访问过,且是圈圈
queue.offer(new int[]{i, j});//入队
visit[i][j] = true;//标志访问
int flag = 1;//是否扩展到边边,如果没有扩展到边边则为默认值1,如果扩展到边边则为0
while(!queue.isEmpty()){//队列不为空
int[] now = queue.poll();//出队
int x = now[0];//x坐标
int y = now[1];//y坐标
for(int k = 0; k < 4; k++){//上下左右移动
int nx = x + dx[k];
int ny = y + dy[k];
if(nx >= 0 && nx < r && ny >= 0 && ny < c){//边界判断
if(!visit[nx][ny] && board[nx][ny] == 'O'){//是圈圈且没有访问过
queue.offer(new int[]{nx, ny});//入队
visit[nx][ny] = true;//置为访问过
}
}else{//超过边界
flag = 0;
}
}
}
if(flag == 1){//没有扩展到边界
board[i][j] = 'X';//置为x
queue.offer(new int[]{i, j});//入队
while(!queue.isEmpty()){//队列不为空
int[] now = queue.poll();//出队
int x = now[0];
int y = now[1];
for(int k = 0; k < 4 ; k++){//搜索周围圈圈
int nx = x + dx[k];
int ny = y + dy[k];
if(nx >= 0 && nx < r && ny >= 0 && ny < c && visit[nx][ny] && board[nx][ny] == 'O'){//是圈圈
board[nx][ny] = 'X';//置为叉叉
queue.offer(new int[]{nx ,ny});//入队
}
}
}
}
}
visit[i][j] = true;
}
}
return ;
}
}