leetCode-Surrounded Regions DFS与BFS解法

问题描述
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区域全部替换为Z,则剩下的O区域则肯定不与边界连通,可以直接替换为X,从而最后再将Z替换为原来的O。
其中的关键就在第一步,在边界上找到某个O后,通过BFS或者DFS将所有与该O连通的O替换为Z。

void fill_DFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
    if(board[i][j] == target)
    {
        stack<pair<int ,int>>s;
        s.push(make_pair(i,j));
        board[i][j] = c; 
        while(!s.empty())
        {
            int x = s.top().first;
            int y = s.top().second;
            //board[x][y] = c;
            s.pop();
            if(x > 0 && board[x-1][y] == target) { board[x-1][y] = c ; s.push(make_pair(x-1,y));}
            if(x < board.size()-1 && board[x+1][y] == target) {board[x+1][y] =c; s.push(make_pair(x+1,y));}
            if(y > 0 && board[x][y-1] == target)  {board[x][y-1] = c;s.push(make_pair(x,y-1));}
            if(y < board[0].size()-1 && board[x][y+1] == target) {board[x][y+1] = c ;s.push(make_pair(x,y+1));}

        }
    }
}




void fill_BFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
    if(board[i][j] == target)
    {
        queue<pair<int ,int>>q;
        q.push(make_pair(i,j));
        board[i][j] = c; 

        while(!q.empty())
        {
            int x = q.front().first;
            int y = q.front().second;
           // board[x][y] = c;
            q.pop();
            if(x > 0 && board[x-1][y] == target){ board[x-1][y] = c ; q.push(make_pair(x-1,y));}
            if(x < board.size()-1 && board[x+1][y] == target) {board[x+1][y] =c; q.push(make_pair(x+1,y));}
            if(y > 0 && board[x][y-1] == target) {board[x][y-1] = c;q.push(make_pair(x,y-1));}
            if(y < board[0].size()-1 && board[x][y+1] == target) {board[x][y+1] = c ;q.push(make_pair(x,y+1));}

        }
    }
}




class Solution {
public:
    void solve(vector<vector<char>> &board) {
        if(board.size() == 0) return ;
        for(int i = 0 ; i < board.size(); ++i)
        {
            if(board[i][0] == 'O') fill_DFS(board,i,0,'O','Z');
            if(board[i][board[0].size()-1] == 'O') fill_DFS(board,i,board[0].size()-1,'O','Z');
        }

        for(int i = 0 ; i < board[0].size() ;++i)
        {
            if(board[0][i] == 'O') fill_DFS(board,0,i,'O','Z');
            if(board[board.size()-1][i] == 'O') fill_DFS(board,board.size()-1,i,'O','Z');
        }

        for(int i = 0; i<board.size() ;++i)
        {
            for(int j = 0; j < board[0].size() ;++j)
            {
                if(board[i][j] == 'O') board[i][j] = 'X';
                else if(board[i][j] == 'Z') board[i][j] = 'O';
            }
        }
}};

注意:BFS与DFS均要记录元素是否已经被访问。!!!
一开始,BFS代码如下,怎么也跑不出结果,通过调试发现代码陷入了循环之中:

void fill_BFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
    if(board[i][j] == target)
    {
        queue<pair<int ,int>>q;
        q.push(make_pair(i,j));


        while(!q.empty())
        {
            int x = q.front().first;
            int y = q.front().second;
            board[x][y] = c; //注意这里,在出队列时才替换元素导致入队列时出现大量重复
            q.pop();
           if (x > 0 && board[x - 1][y] == target) q.push(make_pair(x - 1, y));
           if (x < board.size() - 1 && board[x + 1][y] == target) q.push(make_pair(x + 1, y));
           if (y > 0 && board[x][y - 1] == target) q.push(make_pair(x, y - 1));
           if (y < board[0].size() - 1 && board[x][y + 1] == target) q.push(make_pair(x, y + 1));

        }
    }
}

原因就是不是在入队列前就已经把’O’ 变为’Z’, 导致不能判断相邻的元素是否已经入队列,造成队列中包含大量的重复元素,使得效率极低。
所以DFS与BFS均应该利用一个额外的数组或者在原有数据上使用某种标记,来标志该元素已经被访问过。

猜你喜欢

转载自blog.csdn.net/werweqg/article/details/45312789