[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


思路:之前用的递归做DFS,新加了test case之后爆栈了,所以该用BFS去做。整体思想是,被围住的区域一定和周围的O是不连通的,因此想到从四周的O入手,向里面渗透,并且标记所有渗透到的O为D. 这样做之后,仍然为O的点就肯定是被围住的点了。之后再遍历一遍矩阵,将D恢复成O,因为D是没有被围住的O,同时将O设成X.


class Solution {
public:
    void solve(vector<vector<char>> &board) {
        if (board.size() == 0 || board[0].size() == 0) return;
        int row = (int)board.size();
        int col = (int)board[0].size();
        //permeate form the edges
        queue<pair<int, int>> permeated;
        for (int i = 0; i < row; ++i) {
            if (board[i][0] == 'O') {
                board[i][0] = 'D';
                permeated.push(make_pair(i, 0));
            }
            if (board[i][col-1] == 'O') {
                board[i][col-1] = 'D';
                permeated.push(make_pair(i, col - 1));
            }
        }
        for (int j = 1; j < col - 1; ++j) {
            if (board[0][j] == 'O') {
                board[0][j] = 'D';
                permeated.push(make_pair(0, j));
            }
            if (board[row-1][j] == 'O') {
                board[row-1][j] = 'D';
                permeated.push(make_pair(row - 1, j));
            }
        }
        while (!permeated.empty()) {
            int temp_row = permeated.front().first;
            int temp_col = permeated.front().second;
            permeated.pop();
            // check up
            if (temp_row - 1 >= 0 && board[temp_row-1][temp_col] == 'O') {
                board[temp_row-1][temp_col] = 'D';
                permeated.push(make_pair(temp_row - 1, temp_col));
            }
            // check down
            if (temp_row + 1 < row && board[temp_row+1][temp_col] == 'O') {
                board[temp_row+1][temp_col] = 'D';
                permeated.push(make_pair(temp_row + 1, temp_col));
            }
            // check left
            if (temp_col - 1 >= 0 && board[temp_row][temp_col-1] == 'O') {
                board[temp_row][temp_col-1] = 'D';
                permeated.push(make_pair(temp_row, temp_col - 1));
            }
            // check down
            if (temp_col + 1 < col && board[temp_row][temp_col+1] == 'O') {
                board[temp_row][temp_col+1] = 'D';
                permeated.push(make_pair(temp_row, temp_col + 1));
            }
        }
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                // cover all the surrounded regions
                if (board[i][j] == 'O') board[i][j] = 'X';
                // restore the non-surrounded regions
                else if (board[i][j] == 'D') board[i][j] = 'O';
            }
        }
    }
};


总结:做BFS的时候,需要注意的细节是,在一个点入队之前就把那个点标记为D,而不是等到出队后再标记。如果出队后再标记,那么在出队前这个点一直是O,可能被访问多次,多次被加入到队列中,造成冗余。复杂度为O(mn). 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值