BFS——surrounded region

Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

For example,

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

大多数人,包括笔者,看到本题第一反应就是,找出成片的 ‘O’的集合即可,只要不碰到边界。啊哦!反过来想,不碰到边界,那也就是说,我从边界出发能够到达(从上下左右四个方向)的点一定是不能被变成 ‘X’的, 显然,这是个BFS、DFS的问题了。于是笔者参考网上已有的大牛的代码,写下了如下的两个版本:

BFS:

class Solution {

public:
    void solve(vector<vector<char> > &board) {
        
        if(board.empty()) return;
        
        int row = board.size();
        int column = board[0].size();

        if(row <= 2 || column <= 2)
            return;

        //find start point
        vector<pair<int,int> > start;

//如果为O,才加入,表示从O开始BFS!!!找边界!!!

        for(int i = 0 ; i < row ; ++i)
        {
            if(board[i][column-1] == 'O' )
            {
                board[i][column-1] = 'D';
                start.push_back(make_pair(i,column-1));
            }

            if(board[i][0] == 'O' )
            {
                board[i][0] = 'D';
                start.push_back(make_pair(i,0));
            }
        }

        for(int i = 1 ; i < column - 1 ; ++i)
        {
            if(board[row-1][i] == 'O' )
            {
                board[row-1][i] = 'D';
                start.push_back(make_pair(row-1,i));
            }

            if(board[0][i] == 'O' )
            {
                board[0][i] = 'D';
                start.push_back(make_pair(0,i));
            }
        }

        
        
        //不能用迭代器,会改变start
        
        const static int PATH[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
        
        while(!start.empty())
        {
            pair<int,int> p = start.back();
            start.pop_back();
            
            for(int i = 0 ; i < 4; ++i)
            {
                int x = p.first, y = p.second;
                
                x += PATH[i][0];
                y += PATH[i][1];
                
                //为X的直接不用考虑!!为D的已经考虑过了!!!
                if(x < 0 || x >= row || y < 0 || y >= column || board[x][y] != 'O' ) continue;
                
                if(board[x][y] == 'O') 
                {
                    board[x][y] = 'D';
                    start.push_back(make_pair(x,y));
                }
            }
        }
        
        for(int i = 0 ; i < row; ++i)
        {
            for(int j = 0 ; j < column ; ++j)
            {
                if(board[i][j] == 'D')
                {
                    board[i][j] = 'O';
                }
                else 
                {
                    board[i][j] = 'X';
                }
            }
        }
        
    }
};

DFS: 比较简洁,但是在leetcode上出现的问题是,runtime error。。对于一个较大的例子,忘各位帮忙解答:

class Solution {
    
private:
void dfs(vector<vector<char> > &board, int x, int y, const int row, const int column)
{
    if(x < 0  || x >= row || y < 0 || y >= column || board[x][y] == 'O' ) return;
    board[x][y] = 'D';
    dfs(board, x-1,y , row, column);
    dfs(board, x+1,y , row, column);
    dfs(board, x,y-1 , row, column);
    dfs(board, x,y+1 , row, column);
    
}

public:
    void solve(vector<vector<char>> &board) {
        
        if(board.empty()) return;
        
        int row = board.size();
        int column = board[0].size();
        
        for(int i = 0 ; i < column ; ++i)
        {
            dfs(board, 0, i, row, column);
            dfs(board, row-1, i, row, column);
        }
        for(int i = 1 ; i < row-1 ; ++i)
        {
            dfs(board, i , 0, row , column);
            dfs(board, i, column-1, row,column);
        }
        
        for(int i = 0 ; i < row; ++i)
        {
            for(int j = 0 ; j < column ; ++j)
            {
                if(board[i][j] == 'D')board[i][j] = 'O';
                else board[i][j] = 'X';
            }
        }
    }
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值