给定一个二维的矩阵,包含 ‘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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surrounded-regions
代码思路:
这道题的思路没什么好说的,就是一个深度和广度搜索,搜索到一片的O判断这片O是否和四个边相接,如果和四个边相接则不用把O改成X,否则改成X。
代码如下:
public void solve(char[][] board) {
HashSet<String> map=new HashSet<String>();
HashSet<String> queue=new HashSet<String>();
int i=0,n=0;
String str;
String strs[];
int flag=1;
int rowlength=board.length;
if(rowlength==0)return;
int columnlength=board[0].length;
for(i=0;i<rowlength;i++) {
for(n=0;n<columnlength;n++) {
if(board[i][n]=='O') {
str=String.valueOf(i)+"-"+String.valueOf(n);
flag=1;
if(!map.contains(str)&&board[i][n]=='O') {
queue.add(str);
map.add(str);
flag=flag*bfs(board,map,queue,i,n,flag);
}
if(flag==1) {
for(String str1: queue) {
strs=str1.split("-");
board[Integer.parseInt(strs[0])][Integer.parseInt(strs[1])]='X';
}
queue.clear();
}else {
queue.clear();
}
}
}
}
}
public static int bfs(char [][] board,HashSet map,HashSet que,int i,int n,int flag) {
String str;
if(board[i][n]=='X')return 1;
if(i+1<board.length&&n<board[0].length&&board[i+1][n]!='X') {
str=String.valueOf(i+1)+"-"+String.valueOf(n);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=bfs(board,map,que,i+1,n,flag)*flag;
}
}
if(i<board.length&&n+1<board[0].length&&board[i][n+1]!='X') {
str=String.valueOf(i)+"-"+String.valueOf(n+1);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=bfs(board,map,que,i,n+1,flag)*flag;
}
}
if(i-1>=0&&n<board[0].length&&board[i-1][n]!='X') {
str=String.valueOf(i-1)+"-"+String.valueOf(n);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=flag*bfs(board,map,que,i-1,n,flag);
}
}
if(i<board.length&&n-1>=0&&board[i][n-1]!='X') {
str=String.valueOf(i)+"-"+String.valueOf(n-1);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=flag*bfs(board,map,que,i,n-1,flag);
}
}
if((i==0||n==0||i==board.length-1||n==board[0].length-1)&&board[i][n]=='O') {
return 0;
}
return flag;
}
以上是博主的代码,具体情况和判断的细节大多需要自己调整自己的代码,这种题还是很考验自己的代码结构,和判断逻辑的。
结果如下:
看到还有人看我的挺快的,我就再写写刷代码时候的踩的坑分享一下。
- 判断顺序
public static int bfs(char [][] board,HashSet map,HashSet que,int i,int n,int flag) {
String str;
if(board[i][n]=='X')return 1;
if(i+1<board.length&&n<board[0].length&&board[i+1][n]!='X') {
str=String.valueOf(i+1)+"-"+String.valueOf(n);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=bfs(board,map,que,i+1,n,flag)*flag;
}
}
if(i<board.length&&n+1<board[0].length&&board[i][n+1]!='X') {
str=String.valueOf(i)+"-"+String.valueOf(n+1);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=bfs(board,map,que,i,n+1,flag)*flag;
}
}
if(i-1>=0&&n<board[0].length&&board[i-1][n]!='X') {
str=String.valueOf(i-1)+"-"+String.valueOf(n);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=flag*bfs(board,map,que,i-1,n,flag);
}
}
if(i<board.length&&n-1>=0&&board[i][n-1]!='X') {
str=String.valueOf(i)+"-"+String.valueOf(n-1);
if(!map.contains(str)) {
map.add(str);
que.add(str);
flag=flag*bfs(board,map,que,i,n-1,flag);
}
}
if((i==0||n==0||i==board.length-1||n==board[0].length-1)&&board[i][n]=='O') {
return 0;
}
return flag;
}
这个写的是广度搜索的代码,但是熟悉代码的朋友应该了解最后的return 0的判断平常写在最上面,为啥博主放在了最后面。
如果放到了上面有如下代码结构:
public static int bfs(char [][] board,HashSet map,HashSet que,int i,int n,int flag) {
String str;
if(board[i][n]=='X')return 1;
if(i+1<board.length&&n<board[0].length&&board[i+1][n]!='X') {
***
flag=bfs(board,map,que,i+1,n,flag)*flag;
**
}
if(i<board.length&&n+1<board[0].length&&board[i][n+1]!='X') {
***
flag=bfs(board,map,que,i,n+1,flag)*flag;
***
}
if(i-1>=0&&n<board[0].length&&board[i-1][n]!='X') {
***
flag=flag*bfs(board,map,que,i-1,n,flag);
***
}
if(i<board.length&&n-1>=0&&board[i][n-1]!='X') {
***
flag=flag*bfs(board,map,que,i,n-1,flag);
***
}
if((i==0||n==0||i==board.length-1||n==board[0].length-1)&&board[i][n]=='O') {
return 0;
}
return flag;
}
有如下的反例:
X X X O O O X
X X X O X X X
X X X X X X X
上述结构的代码在判断到board[1,3]的时候,由于if(i<board.length&&n-1>=0&&board[i][n-1]!='X')
中有判断board[i][n-1]是否和X相等,所以board[1,3]只会判断board[i-1][n],但是由于board[i-1][n]在做第一行的时候已经在map中,所以并不会进入bfs(board[i-1][n]),进而这个位置会返回1。
就会有如下错误输出
X X X O O O X
X X X X X X X
X X X X X X X
- hashset和queue的使用
HashSet<String> queue=new HashSet<String>();
这一行代码熟悉使用的人肯定会发现使用的问题。从代码逻辑来说这个queue是用来当做队列使用的,用于广度优先搜索。
但是queue que=new LinkedList();
如果按照这个进行bfs的话,在返回函数后,que中的所有数据并不会返回,换句话说Queue只能向下传递,如果不写到返回值的话不会返回到上层。
而hashSet则可以,所以把hashset当成queue使用。