Leetcode: 130. Surrounded Region(Week7, Medium)

注: 本题使用BFS算法求解

Leetcode 130
Given a 2D board containing ‘X’ and ‘O’ (the letter 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

题意: 给一块二维的board,里面包含‘X’和‘O’字符。现要实现一个算法,将被‘X’包围的一个或多个‘O’替换成‘X’,而没有被包围的不发生改变。这有点类似于围棋吃子的原理。

思路: 不被‘X’包围的‘O’,一定位于边缘或者与位于边缘的‘O’连通。

算法:

  1. 定义两个数组,一个用于标识元素‘O’是否被访问过,一个用于标识元素‘O’是否可以被替换成‘X’;
  2. 使用两个for循环,将四个边缘上的‘O’加入队列中,然后进行BFS,找出与这些‘O’连通的‘O’;
  3. 在处理每次队列的结点时,标识已访问,且不可以替换;
  4. 最后在遍历所有元素,将可以替换的‘O’替换成‘X’

代码如下:

/* 2017/10/21 Leetcode 130 主要思路: 找出边缘的所有符号‘O’,使用BFS找到与其相邻的‘O’,然后对他们做标记,在下一次遍历时将没有标记的‘O’替换成‘X’ */
class Solution {
public:
    void solve(vector<vector<char>>& board) {

        /* 避免runtime error */
        if (board.size() == 0 || board[0].size() == 0) return;

        /* 表示数组的定义 */
        vector<bool> isAccess(board.size()*board[0].size(), 0);
        vector<bool> canDelete(board.size()*board[0].size(), 1);

        /* BFS遍历的数据机构定义 */
        queue<vector<int>> q;

        /* 将边缘的‘O’压到队列中 */
        for (int i = 0; i < board[0].size(); i++) {
            if (board[0][i] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = 0;
                vec[1] = i;
                q.push(vec);
            }
            if (board[board.size()-1][i] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = board.size()-1;
                vec[1] = i;
                q.push(vec);
            }
        }
        for (int i = 0; i < board.size(); i++) {
            if (board[i][0] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = i;
                vec[1] = 0;
                q.push(vec);
            }
            if (board[i][board[0].size()-1] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = i;
                vec[1] = board[0].size()-1;
                q.push(vec);
            }
        }

        /* 对边缘的‘O’进行BFS操作 */
        while(!q.empty()) {
            vector<int> front = q.front();
            q.pop();
            isAccess[front[0]*board[0].size()+front[1]] = 1;
            canDelete[front[0]*board[0].size()+front[1]] = 0;
            if (front[0] > 0 
                && isAccess[(front[0]-1)*board[0].size()+front[1]] == 0
                && board[front[0]-1][front[1]] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = front[0] - 1;
                vec[1] = front[1];
                q.push(vec);
            }
            if (front[0] < board.size()-1
               && isAccess[(front[0]+1)*board[0].size()+front[1]] == 0
               && board[front[0]+1][front[1]] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = front[0] + 1;
                vec[1] = front[1];
                q.push(vec);
            }
            if (front[1] > 0
               && isAccess[front[0]*board[0].size()+front[1]-1] == 0
               && board[front[0]][front[1]-1] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = front[0];
                vec[1] = front[1]-1;
                q.push(vec);
            }
            if (front[1] < board[0].size()-1
               && isAccess[front[0]*board[0].size()+front[1]+1] == 0
               && board[front[0]][front[1]+1] == 'O') {
                vector<int> vec(2, 0);
                vec[0] = front[0];
                vec[1] = front[1] + 1;
                q.push(vec);
            }
        }

        /* 再次遍历,将没有标记的‘O’替换成‘X’ */
        for (int i = 0; i < board.size(); i++) {
            for (int j = 0; j < board[0].size(); j++) {
                if (board[i][j] == 'O' && canDelete[i*board[0].size()+j] == 1)
                    board[i][j] = 'X';
            }
        }
    }
};

以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!

点赞