给定一个二维的矩阵,包含 'X''O'字母 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’ 最终都会被填充为 ‘X’。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

    1. 分析:<br /> 任何边界上的O都不会被填充为X; 所以: 所有不被包围的O都直接或间接与边界上O相连;<br /> 1、先判断O是否与边界上的O相连,以边界上的O为起点,采用深度优先搜索的方式对直接或间接<br /> 与边界上的O相连O标记为M;<br /> 2、对于没有被标记的M, 则其被X包围,应该用X填充;

    一、深度优先搜索(递归)

    int m;
    int n;
    void dfs_mark(vector<vector<char>> &board, int row, int col)
    {
        if(row<0 || col<0 || row>=m || col>=n || board[row][col]!='O')
            return;
        board[row][col]='M';
        dfs_mark(board, row-1, col); // up
        dfs_mark(board, row+1, col); // down
        dfs_mark(board, row, col-1); // left
        dfs_mark(board, row, col+1); // right
    }
    
    void solve(vector<vector<char>>& board) 
    {
        m = board.size();
        if (m<=2)
            return;
        n = board[0].size();
    
        // vertical board
        for(int i=0; i<m; ++i)
        {
            dfs_mark(board, i, 0);
            dfs_mark(board, i, n-1);
        }
    
        // horizontal board
        for(int j=1; j<n-1; ++j)
        {
            dfs_mark(board, 0, j);
            dfs_mark(board, m-1, j);
        }
    
        // fill 'O' with 'X'
        for(int i=0; i<m; ++i)
        {
            for(int j=0; j<n; ++j)
            {
                if (board[i][j] == 'O')
                    board[i][j] = 'X';
                else if(board[i][j] == 'M')
                    board[i][j] = 'O';
            }
        }
    }
    // 时间复杂度:O(m*n)
    // 空间复杂度:O(m*n)
    

    二、广度优先搜索(用到队列queue>)

    const int dx[4] = {-1, 1, 0, 0};
    const int dy[4] = {0, 0, -1, 1};
    void bfs_mark(vector<vector<char>> &board, int m, int n)
    {
        queue<pair<int, int>> Q;
        // vertical border
        for(int i=0; i<m; ++i)
        {
            if (board[i][0] == 'O')
                Q.emplace(i, 0);
            if (board[i][n-1] == 'O')
                Q.emplace(i, n-1);
        }
    
        // horizontal border
        for(int j=1; j<n-1; ++j)
        {
            if(board[0][j] == 'O')
                Q.emplace(0, j);
            if (board[m-1][j] == 'O')
                Q.emplace(m-1, j);
        }
    
        while(!Q.empty()){
            int x = Q.front().first;
            int y = Q.front().second;
            Q.pop();
            board[x][y] = 'M';
    
            // up, down, left, right
            for(int k=0; k<4; ++k)
            {
                int x_dx = x + dx[k];
                int y_dy = y + dy[k];
                if (x_dx<0 || x_dx>=m || y_dy<0 || y_dy>=n || board[x_dx][y_dy]!='O')
                    continue;
                Q.emplace(x_dx, y_dy);
            }
        }
    }
    void solve(vector<vector<char>>& board)
    {
        int m = board.size();
        if (m<=2)
            return;
        int n = board[0].size();
        bfs_mark(board, m, n);
    
        // fill O with X
        for(int i=0; i<m; ++i)
        {
            for(int j=0; j<n; ++j)
            {
                if (board[i][j] == 'M')
                    board[i][j] = 'O';
                else if (board[i][j] == 'O')
                    board[i][j] = 'X';
            }
        }
    }
    

    欢迎交流,不吝赐教!