leetcode 130. 被围绕的区域

问题描述

给定一个二维的矩阵,包含 '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'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

代码

class Solution {
public:
    void solve(vector<vector<char>>& board) {
        int m = board.size();
        if(m < 1)return;
        int i,j,n = board[0].size();
        for(i = 0; i < m; ++i)
        {
            if(board[i][0] == 'O')//把最左边与'O'连通的变为'#'
                dfs(i,0,m,n,board);
            if(board[i][n-1] == 'O')//把最右边与'O'连通的变为'#'
                dfs(i,n-1,m,n,board);
        }
        for(j = 0; j < n; ++j)
        {
            if(board[0][j] == 'O')//把最上边与'O'连通的变为'#'
                dfs(0,j,m,n,board);
            //cout<<board[m-1][j]<<" ";
            if(board[m-1][j] == 'O')//把最下边与'O'连通的变为'#'
                dfs(m-1,j,m,n,board);
        }
        //剩下的'O'都不与边界相连可以变为'X','#'重新变为'O'
        for(i = 0; i < m; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                if(board[i][j] == 'O')board[i][j] = 'X';
                else if(board[i][j] == '#')board[i][j] = 'O';
            }
        }
    }
    void dfs(int i,int j,int& m,int& n,vector<vector<char>>& board)
    {
        if(i < 0 || j < 0 || i >= m || j >= n || board[i][j]!='O')
            return;
        board[i][j] = '#';
        if(i-1>0 && board[i-1][j]=='O')
            dfs(i-1,j,m,n,board);
        if(i+1<m && board[i+1][j]=='O')
            dfs(i+1,j,m,n,board);
        if(j-1>0 && board[i][j-1]=='O')
            dfs(i,j-1,m,n,board);
        if(j+1<n && board[i][j+1]=='O')
            dfs(i,j+1,m,n,board);
    }
};

结果

执行用时 :24 ms, 在所有 C++ 提交中击败了99.66%的用户
内存消耗 :10.1 MB, 在所有 C++ 提交中击败了100.00%的用户

代码2(循环)

class Solution {
public:
    int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
    void solve(vector<vector<char>>& board) {
        int m = board.size();
        if(m < 1)return;
        int i,j,n = board[0].size();
        for(i = 0; i < m; ++i)
        {
            if(board[i][0] == 'O')
                bfs(i,0,m,n,board);
            if(board[i][n-1] == 'O')
                bfs(i,n-1,m,n,board);
            
        }
         for(j = 0; j < n; ++j)
        {
            if(board[0][j] == 'O')
                bfs(0,j,m,n,board);
            if(board[m-1][j] == 'O')
                bfs(m-1,j,m,n,board);
            
        }
        //剩下的'O'都不与边界相连可以变为'X','#'重新变为'O'
        for(i = 0; i < m; ++i)
        {
            for(j = 0; j < n; ++j)
            {
                if(board[i][j] == 'O')board[i][j] = 'X';
                else if(board[i][j] == '#')board[i][j] = 'O';
            }
        }
    }
    void bfs(int i,int j,int& m,int& n,vector<vector<char>>& board)
    {
        queue<int> q;
        board[i][j] = '#';
        q.push(i*n+j);//注意是乘n
        while(!q.empty())
        {
            int ind = q.front();
            q.pop();
            int indx = ind/n,indy = ind%n;
            for(int k = 0; k < 4; ++k)
            {
                int ii = indx + dir[k][0];
                int jj = indy + dir[k][1];
                if(ii > 0 && ii < m && jj > 0 && jj < n && board[ii][jj] == 'O')
                {
                    board[ii][jj] = '#';
                    q.push(ii*n+jj);
                }
            }
        }   
    }
};

结果

执行用时 :36 ms, 在所有 C++ 提交中击败了77.31%的用户
内存消耗 :11 MB, 在所有 C++ 提交中击败了100.00%的用户
posted @ 2020-06-06 09:58  曲径通霄  阅读(228)  评论(0编辑  收藏  举报