1. 程式人生 > >LeetCode | Surrounded Regions(包圍的區域)

LeetCode | Surrounded Regions(包圍的區域)

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即可。

可以利用深度優先遍歷,也可以用廣度優先遍歷。廣度優先時,當碰到O的結點就將這個座標加入到棧中。

深度優先遍歷:

//深度優先
class Solution {
public:
    void solve(vector<vector<char>> &board) {
        if(board.size() == 0 || board[0].size() == 0)
            return ;
        m = board.size();
        n = board[0].size();
        for(int i = 0;i < n;i++){
            traverse(0,i,board);
            traverse(m-1,i,board);
        }
        for(int i = 0;i < m;i++){
            traverse(i,0,board);
            traverse(i,n-1,board);
        }
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                board[i][j] = board[i][j] == 'Z' ? 'O' : 'X';
            }
        }
    }
    //
    void traverse(int x,int y,vector<vector<char>> &board){
        if(x>=0 && x < m && y>=0 && y<n && board[x][y]=='O'){
            board[x][y] = 'Z';      //將要保留的值賦一個額外的引數,更容易判斷
            traverse(x-1,y,board);  //有了入口條件,就隨便上下左右遞迴,不用擔心越界問題
            traverse(x+1,y,board);
            traverse(x,y-1,board);
            traverse(x,y+1,board);
        }
    }
private:
    int m,n;
};


廣度優先遍歷

//廣度優先
class Solution {
public:
    void solve(vector<vector<char>> &board) {
        if(board.size() == 0 || board[0].size() == 0)
            return ;
        m = board.size();
        n = board[0].size();
        for(int i = 0;i < n;i++){
            if(board[0][i] == 'O')
                traverse(0,i,board);
            if(board[m-1][i] == 'O')
                traverse(m-1,i,board);
        }
        for(int i = 0;i < m;i++){
            if(board[i][0] == 'O')
                traverse(i,0,board);
            if(board[i][n-1] == 'O')
                traverse(i,n-1,board);
        }
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                board[i][j] = board[i][j] == 'Z' ? 'O' : 'X';
            }
        }
    }

    void add(int x,int y,vector<vector<char>> &board){
        if(x>=0 && x < m && y>=0 && y<n && board[x][y]=='O'){
            q.push(x*n+y);
            board[x][y] = 'Z';
        }
    }

    void traverse(int x,int y,vector<vector<char>> &board){
        add(x,y,board);
        while(!q.empty()){  //利用佇列,來實現層序遍歷
            int p = q.front();
            q.pop();
            x = p/n;
            y = p%n;
            add(x-1,y,board);   //遞歸向棧中加入字元為‘O’的字元
            add(x+1,y,board);
            add(x,y-1,board);
            add(x,y+1,board);
        }

    }
private:
    queue<int> q;
    int m,n;
};