注: 本题使用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’连通。
算法:
- 定义两个数组,一个用于标识元素‘O’是否被访问过,一个用于标识元素‘O’是否可以被替换成‘X’;
- 使用两个for循环,将四个边缘上的‘O’加入队列中,然后进行BFS,找出与这些‘O’连通的‘O’;
- 在处理每次队列的结点时,标识已访问,且不可以替换;
- 最后在遍历所有元素,将可以替换的‘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';
}
}
}
};
以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!