题目:
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.
给定一个包含 'x' 和 'o' 的二维板,找到所有被 'x' 包含的区域。把区域中的 'o' 用 'x' 替换。
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
思路:
对最外面一层判断,即第一行和最后一行,第一列和最后一列,在最外面一层的点中,如果当前点为 'O' 则与当前点相邻的点中为 ’O' 的不能替换。因为没有完全被'X'包围。然后与这个 'O' 点相邻的点为 'O' 的点也不能替换。以此类推可以使用BFS广度优先遍历当前点的周围的相邻的点。
代码:
class Solution {
public:
void solve(vector<vector<char>> &board)
{
if(board.empty() || board[0].empty())
return;
int row = board.size();
int col = board[0].size();
//先对第一列和最后一列上的点判断
for(int i = 0 ; i < row ; i++)
{
//如果第一列的某个点是'O',则对这个点进行广搜,下面同理
if(board[i][0] == 'O')
bfs(board,i,0);
if(board[i][col-1] == 'O')
bfs(board,i,col-1);
}
//对第一行和最后一行上的点进行判断
for(int j = 0 ; j < col ; j++)
{
if(board[0][j] == 'O')
bfs(board,0,j);
if(board[row-1][j] == 'O')
bfs(board,row-1,j);
}
//如果当前点被标记为'*',则说明不是内部的'O'。否则其他点都置为'X'(包括原来为'X'的和内部点'O')
for(int i = 0 ; i < row ; i++)
{
for(int j = 0 ; j < col ; j++)
{
if(board[i][j] == '*')
board[i][j] = 'O';
else
board[i][j] = 'X';
}
}
}
//广搜,第一层是当前传进来的点,第二层是这个点的上下左右四个点的判断,第三层为第二层的各个点的上下左右四个点......
void bfs(vector<vector<char>> &board , int i , int j)
{
int row = board.size();
int col = board[0].size();
typedef pair<int,int> stat;
queue<stat> que;
que.push(stat(i,j));//先入队列
board[i][j] = '*';//置为'*'
while(!que.empty())
{
stat tmp = que.front();
que.pop();
int x = tmp.first,y = tmp.second;
//判断上一个点是否为'O'
if(isLegal(board,x-1,y))
{
que.push(make_pair(x-1,y));
board[x-1][y] = '*';
}
//下一个点
if(isLegal(board,x+1,y))
{
que.push(make_pair(x+1,y));
board[x+1][y] = '*';
}
//前一个点
if(isLegal(board,x,y-1))
{
que.push(make_pair(x,y-1));
board[x][y-1] = '*';
}
//后一个点
if(isLegal(board,x,y+1))
{
que.push(make_pair(x,y+1));
board[x][y+1] = '*';
}
}
}
//判断当前点是否是'O'
bool isLegal(vector<vector<char>> &board,int i , int j)
{
return !(i<0 || i>=board.size() || j<0 || j>= board[0].size() || board[i][j] != 'O');
}
};
代码2:
没有AC,报 runtime error 错误,不知道为什么,贴上来吧
class Solution {
public:
void solve(vector<vector<char>> &board)
{
if(board.empty() || board[0].empty())
return;
int row = board.size();
int col = board[0].size();
//先对第一列和最后一列上的点判断
for(int i = 0 ; i < row ; i++)
{
//如果第一列的某个点是'O',则对这个点进行广搜,下面同理
if(board[i][0] == 'O')
dfs(board,i,0);
if(board[i][col-1] == 'O')
dfs(board,i,col-1);
}
//对第一行和最后一行上的点进行判断
for(int j = 0 ; j < col ; j++)
{
if(board[0][j] == 'O')
dfs(board,0,j);
if(board[row-1][j] == 'O')
dfs(board,row-1,j);
}
//如果当前点被标记为'*',则说明不是内部的'O'。否则其他点都置为'X'(包括原来为'X'的和内部点'O')
for(int i = 0 ; i < row ; i++)
{
for(int j = 0 ; j < col ; j++)
{
if(board[i][j] == '*')
board[i][j] = 'O';
else
board[i][j] = 'X';
}
}
}
//广搜,第一层是当前传进来的点,第二层是这个点的上下左右四个点的判断,第三层为第二层的各个点的上下左右四个点......
void dfs(vector<vector<char>> &board , int i , int j)
{
if(!isLegal(board,i,j))
return;
board[i][j] = '*';
dfs(board,i-1,j);
dfs(board,i+1,j);
dfs(board,i,j-1);
dfs(board,i,j+1);
}
//判断当前点是否是'O'
bool isLegal(vector<vector<char>> &board,int i , int j)
{
return !(i<0 || i>=board.size() || j<0 || j>= board[0].size() || board[i][j] != 'O');
}
};