Surrounded Regions

本题看似简单,但处理不当也很容易犯错,比如我就犯错了。。。

先贴我的代码

版本一

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';
                }
            }
        }
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值