LeetCode130 记录一次 java.lang.StackOverflowError的情况
首先贴上错误贴图
看到这里作者还不太明白 直到看到了官方的测试用例就恍然大悟
当我们把我红框选中的代码注释之后 也就是在我的第一次错误代码的情况之下 就会发生这个栈溢出的情况,我们来分析一下 如果我们进入了第二行 第一列这个O的dfs当中 我们根据代码就会去比较这个O的上下左右4个方向 如果我们加上我注释的这句代码 由于第二行 第一列这个O的上方的处于[1,1]位置的O已经把标志位修改成true 此时便不会进入[1,1]这个O的dfs当中 代码将继续往下执行 ,但是由于我的第一次的错误代码没有加这个visited这个判断,代码进入这个[1,1]这个位置的O的dfs当中 当[1,1]位置的O在遍历上下左右的下这个方向时 就又会进入[2,1]这个O的dfs当中 由于没有加visited这个判断条件 [2,1]这个位置的O就又会调用它的上这个方向的[1,1]的O 于是便形成了死循环 造成了栈溢出的异常 要解决这个问题方法就是 加上我红框选中的判断条件 如果该节点已经被标记过 我们便不再进入这次dfs当中 下面贴上正确的完整代码
class Solution {
int[][] move={{0,1},{1,0},{0,-1},{-1,0}};
int m,n;
boolean[][] visited;
public boolean inArea(int x,int y){
return x>=0&&x<m&&y>=0&&y<n;
}
public void dfs(char[][] board,int x,int y,boolean[][] visited){
visited[x][y]=true;
//找这个位置的上下左右四个方向
for(int i=0;i<4;i++){
int newx=x+move[i][0];
int newy=y+move[i][1];
if(inArea(newx,newy)&&!visited[newx][newy]&&board[newx][newy]=='O'){
dfs(board,newx,newy,visited);
}
}
return;
}
public void solve(char[][] board) {
//m表示行
m=board.length;
if(m==0)
return;
//n表示列
n=board[0].length;
visited=new boolean[m][n];
if(m==0||m==0)
return;
for(int i=0;i<n;i++){
//第一行
if(board[0][i]=='O') dfs(board,0,i,visited);
//最后一行
if(board[m-1][i]=='O') dfs(board,m-1,i,visited);
}
for(int j=0;j<m;j++){
//最左列
if(board[j][0]=='O') dfs(board,j,0,visited);
//最右列
if(board[j][n-1]=='O') dfs(board,j,n-1,visited);
}
//通过以上的4个if 把边界上的O和与边界上的O相邻的所有的O找到
//并且把他们标记为true
//双重循环遍历整个数组 如果board[i][j]的元素为O而且这个O不在边界 不和边界的O相邻
//那么此时的O就是我们要替换成X的O 我们替换即可
for(int i=0;i<m;i++){
for( int j=0;j<n;j++){
if(board[i][j]=='O'&&!visited[i][j]){
board[i][j]='X';
}
}
}
return;
}
}