被围绕的区域

问题陈述

给定一个二维的矩阵,包含 ‘X’ 和 ‘O’(字母 O)。

找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。

示例:

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 要特殊处理,只要把边界上的 O 特殊处理了,那么剩下的 O替换成 X 就可以了。问题转化为,如何寻找和边界联通的 O,我们需要考虑如下情况。

1
2
3
4
X X X X
X O O X
X X O X
X O O X

这时候的 O 是不做替换的。因为和边界是连通的。为了记录这种状态,我们把这种情况下的 O 换成 # 作为占位符,待搜索结束之后,遇到 O 替换为 X(和边界不连通的 O);遇到 #,替换回 O(和边界连通的 O)。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Solution{
public void sounded(char[][] board){
if(board==null||board.length==0){//非常重要
return;
}
int m=board.length;
int n=board[0].length;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
boolean isEdge=(i==0||i==m-1||j==0||j==n-1);
if(isEdge&&board[i][j]=='O'){
dfs(board,i,j);
}
}
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(board[i][j]=='O'){
board[i][j]='X';
}
if(board[i][j]=='#'){
board[i][j]='O';
}
}
}
}
public void dfs(char[][] board,int i,int j){
//注意此处多个或运算符连接需空隔好。
if(i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] == 'X' || board[i][j] == '#'){
return;
}
board[i][j]='#';
dfs(board,i+1,j);
dfs(board,i-1,j);
dfs(board,i,j+1);
dfs(board,i,j-1);
}
}