leetcode每日一道(19)逆向思維!模擬圍棋:請捕獲所有的被‘X’包圍的區域

題目描述

現在有一個僅包含‘X’和‘O’的二維板,請捕獲所有的被‘X’包圍的區域
捕獲一個被包圍區域的方法是將被包圍區域中的所有‘O’變成‘X’
例如
X X X X
X O O X
X X O X
X O X X
執行完你給出的函數以後,這個二維板應該變成:
X X X X
X X X X
X X X X
X O X X

思路

我們一般會想到,判斷每個連通的O周圍,是否全是X,是的話則把它替換掉,但是這個操作起來困難很大,首先要找到所有連通的O,然後判斷他們的周圍,也是極麻煩的。現在有一個逆向操作的思路:把所有邊緣上的O,及其連通的區域找出來,標爲Y,剩下的O就是所有要被消除的O,這樣聽起來好像不可思議,但是其實是正確的!
那麼最最關鍵的就是如何找到邊緣的O及其聯通的區域了,思路是深度優先搜索!相信已經不陌生了。

代碼

class Solution {
public:
    /*
        xxxxxxxoxox;
        xxoxxxoxoxx;
        oooxxoxoxxx;
        xxxoooxxoox;
    */
    void solve(vector<vector<char>> &board) {
        int row = board.size();
        int col = board[0].size();
        vector<int> edge;
        for(int i=0; i<row;i++){
            for(int j=0;j<col;j++){
                if((i==0||i==row-1||j==0||j==col-1)&&board[i][j]=='O'){
                    dfs( board,i,j,row,col);
                }
            }
        }
        for(int i=0; i<row;i++){
            for(int j=0;j<col;j++){
                if(board[i][j]=='O'){
                    board[i][j] = 'X';
                }
                else if(board[i][j]=='Y'){
                    board[i][j] = 'O';
                }
            }
        }

    }
    void dfs(vector<vector<char>> &board,int i, int j,int row,int col){
        board[i][j] = 'Y';
        if((i-1>=0)&&board[i-1][j]=='O')
            dfs(board, i-1,j,row,col);
        if((i+1<row)&&board[i+1][j]=='O')
            dfs(board, i+1,j,row,col);
        if((j-1>=0)&&board[i][j-1]=='O')
            dfs(board, i,j-1,row,col);
        if((j+1<col)&&board[i][j+1]=='O')
            dfs(board, i,j+1,row,col);
            
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章