Leetcode:130.被围绕的区域

133 篇文章 0 订阅

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

解题思路:

连通域搜索(广度优先搜索),递归消除。获取整个区域的边缘,在边缘查找O的连通域(一整块全是O),将搜索到的O设置成访问过的结点,随后遍历整个二维区域,将未访问过的区域且值为O的地方设置为X。这是因为,O的连通域只有两种情况,O的边界中存在图的边界,或者是O的边界中没有图的边界(全部被X包围)。

                      

C++代码
class Solution {
public:
    void solve(vector<vector<char>>& board) {
        size_x = board.size();
        if (size_x == 0) return;
        size_y = board[0].size();
        if (size_y == 0) return;
        visit = vector<vector<bool>>(size_x, vector<bool>(size_y, false));
        vector<pair<int, int>> B = getBoard(board);
        int i, j, k;
        for (i = 1; i <= int(B.size()); i++) {
            int x = B[i - 1].first, y = B[i - 1].second;
            if (visit[x - 1][y - 1] == false && board[x - 1][y - 1] == 'O') find(x, y, board);
        }
        for (i = 1; i <= size_x; i++) {
            for (j = 1; j <= size_y; j++) {
                if (board[i - 1][j - 1] == 'O'&&visit[i - 1][j - 1] == false) board[i - 1][j - 1] = 'X';
            }
        }
    }
    vector<pair<int, int>> getBoard(vector<vector<char>>& board) {
        vector<pair<int, int>> res;
        int i;
        for (i = 1; i <= size_x; i++) { 
            res.push_back(pair<int, int>(i, 1)); 
            res.push_back(pair<int, int>(i, size_y));
        }
        for (i = 1; i <= size_y; i++) {
            res.push_back(pair<int, int>(1, i));
            res.push_back(pair<int, int>(size_x, i));
        }
        return res;
    }
    void find(int x, int y, vector<vector<char>>& board) {
        queue<pair<int, int>> Q;
        Q.push(pair<int, int>(x, y));
        while (!Q.empty()) {
            pair<int, int> temp = Q.front();
            if (visit[temp.first - 1][temp.second - 1] == true) { Q.pop(); continue; }
            visit[temp.first - 1][temp.second - 1] = true;
            //查找上下左右是否有未被访问过的O点。
            if (temp.first > 1 && board[temp.first - 2][temp.second - 1] == 'O'&&visit[temp.first - 2][temp.second - 1] == false) Q.push(pair<int, int>(temp.first - 1, temp.second));
            if (temp.first < size_x&&board[temp.first][temp.second - 1] == 'O'&&visit[temp.first][temp.second - 1] == false) Q.push(pair<int, int>(temp.first + 1, temp.second));
            if (temp.second > 1 && board[temp.first - 1][temp.second - 2] == 'O'&&visit[temp.first - 1][temp.second - 2] == false) Q.push(pair<int, int>(temp.first, temp.second - 1));
            if (temp.second < size_y&&board[temp.first - 1][temp.second] == 'O'&&visit[temp.first - 1][temp.second] == false) Q.push(pair<int, int>(temp.first, temp.second + 1));
            Q.pop();
        }
    }
private:
    int size_x, size_y;
    vector<vector<bool>> visit;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值