本题看似简单,但处理不当也很容易犯错,比如我就犯错了。。。
先贴我的代码
版本一
class Solution {
public:
vector<int> rowDir;
vector<int> colDir;
void fill(int row,int col,vector<vector<char> >& board)
{
int m=board.size();
int n=board[0].size();
for(int i=0;i<4;++i)
{
int newRow=row+rowDir[i];
int newCol=col+colDir[i];
if((newRow<0)||(newRow>=m)||(newCol<0)||(newCol>=n))
{
//do nothing, actually, program will never reach this condition
//because we only fill 'inner' regions
}
else if(board[newRow][newCol]=='O')
{
board[newRow][newCol]='X';
fill(newRow,newCol,board);
}
}
}
void dfs(int row,int col,bool& res,vector<vector<bool> >& visit,const vector<vector<char> >& board)
{
int m=board.size();
int n=board[0].size();
for(int i=0;i<4;++i)
{
int newRow=row+rowDir[i];
int newCol=col+colDir[i];
if((newRow<0)||(newRow>=m)||(newCol<0)||(newCol>=n))
{
res=true;
}
else if((!visit[newRow][newCol])&&(board[newRow][newCol]=='O'))
{
visit[newRow][newCol]=true;
dfs(newRow,newCol,res,visit,board);
}
}
}
void solve(vector<vector<char>> &board) {
int m=board.size();
if(m==0)
{
return;
}
int n=board[0].size();
if(n==0)
{
return;
}
//init directions
int a[]={-1,1,0,0};
int b[]={0,0,-1,1};
rowDir.assign(a,a+4);
colDir.assign(b,b+4);
//
vector<vector<bool> > visit(m,vector<bool>(n,false));
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if((!visit[i][j])&&(board[i][j]=='O'))
{
//cout<<"(i,j)="<<"("<<i<<","<<j<<")"<<endl;
bool res=false;
visit[i][j]=true;
dfs(i,j,res,visit,board);
if(!res)
{
board[i][j]='X';
fill(i,j,board);
}
}
}
}
}
};
上述代码把本题当做一个简单的检测连通分量的题来做:检测每一个连同分量,如果其不与边界接壤,那么将其填充为 ‘X’ ,想法很直白很简单,但是大数据报错 RE,基本确定是由于栈空间耗尽报的错,做了一个简单的追踪,似乎在递归深度达到2400左右的时候就报错了,开发环境是VS2010,但总觉得栈空间不应该只有那么一点,准确的结果还有待进一步分析
参考了网上的代码,此题应该采用“从边路往中间夹击”的策略,先把与边界接壤的联通分量排除出去,然后把剩下的填充即可
代码版本二
class Solution {
public:
vector<int> rowDir;
vector<int> colDir;
void dfs(int row,int col,vector<vector<bool> >& visit,const vector<vector<char> >& board)
{
int m=board.size();
int n=board[0].size();
for(int i=0;i<4;++i)
{
int newRow=row+rowDir[i];
int newCol=col+colDir[i];
if((!((newRow<0)||(newRow>=m)||(newCol<0)||(newCol>=n)))&&(!visit[newRow][newCol])&&(board[newRow][newCol]=='O'))
{
visit[newRow][newCol]=true;
dfs(newRow,newCol,visit,board);
}
}
}
void solve(vector<vector<char>> &board) {
int m=board.size();
if(m==0)
{
return;
}
int n=board[0].size();
if(n==0)
{
return;
}
//init directions
int a[]={-1,1,0,0};
int b[]={0,0,-1,1};
rowDir.assign(a,a+4);
colDir.assign(b,b+4);
//
vector<vector<bool> > visit(m,vector<bool>(n,false));
for(int i=0;i<n;++i)
{
if((!visit[0][i])&&(board[0][i]=='O'))
{
visit[0][i]=true;
dfs(0,i,visit,board);
}
if((!visit[m-1][i])&&(board[m-1][i]=='O'))
{
visit[m-1][i]=true;
dfs(m-1,i,visit,board);
}
}
for(int i=0;i<m;++i)
{
if((!visit[i][0])&&(board[i][0]=='O'))
{
visit[i][0]=true;
dfs(i,0,visit,board);
}
if((!visit[i][n-1])&&(board[i][n-1]=='O'))
{
visit[i][n-1]=true;
dfs(i,n-1,visit,board);
}
}
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if((!visit[i][j])&&(board[i][j]=='O'))
{
board[i][j]='X';
}
}
}
}
};
但是依然RE,还需要进一步优化。采用栈来模拟函数调用栈,这样将递归改成了迭代,可以AC通过了。
代码版本三
class Solution {
public:
vector<int> rowDir;
vector<int> colDir;
void dfs(int row,int col,vector<vector<bool> >& visit,const vector<vector<char> >& board)
{
int m=board.size();
int n=board[0].size();
stack<pair<int,int> > stk;
stk.push(make_pair(row,col));
while(!stk.empty())
{
int row=stk.top().first;
int col=stk.top().second;
stk.pop();
for(int i=0;i<4;++i)
{
int newRow=row+rowDir[i];
int newCol=col+colDir[i];
if((!((newRow<0)||(newRow>=m)||(newCol<0)||(newCol>=n)))&&(!visit[newRow][newCol])&&(board[newRow][newCol]=='O'))
{
visit[newRow][newCol]=true;
stk.push(make_pair(newRow,newCol));
}
}
}
}
void solve(vector<vector<char>> &board) {
int m=board.size();
if(m==0)
{
return;
}
int n=board[0].size();
if(n==0)
{
return;
}
//init directions
int a[]={-1,1,0,0};
int b[]={0,0,-1,1};
rowDir.assign(a,a+4);
colDir.assign(b,b+4);
//
vector<vector<bool> > visit(m,vector<bool>(n,false));
for(int i=0;i<n;++i)
{
if((!visit[0][i])&&(board[0][i]=='O'))
{
visit[0][i]=true;
dfs(0,i,visit,board);
}
if((!visit[m-1][i])&&(board[m-1][i]=='O'))
{
visit[m-1][i]=true;
dfs(m-1,i,visit,board);
}
}
for(int i=0;i<m;++i)
{
if((!visit[i][0])&&(board[i][0]=='O'))
{
visit[i][0]=true;
dfs(i,0,visit,board);
}
if((!visit[i][n-1])&&(board[i][n-1]=='O'))
{
visit[i][n-1]=true;
dfs(i,n-1,visit,board);
}
}
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if((!visit[i][j])&&(board[i][j]=='O'))
{
board[i][j]='X';
}
}
}
}
};