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
不知道怎么地这个题一直放着没做。。。读一下题以后发现不难么,bfs或者dfs就可以了,一个数组来标识该点有没有被访问过。
记录下来所有访问过的点,以及一个标识flag,flag表示该点是不是在矩阵的边缘,如果在矩阵的边缘,则相应的连通块没有被X包围,不改动。
如果这个连通块的所有点都不在矩阵边缘,则应该将这个连通块全置为‘X’。
这里,如果是用bfs,则每次bfs完以后,将head置0,然后遍历队列里面的点,就是整个连通块。
如果用dfs,需要维护一个数组,则每次访问一个“有效”点,将这个点加入到这个数组中,然后再统一进行修改或不改动。
而这个题目,我用bfs ac以后,想着写一下dfs,果然,stack over flow了,看来在矩阵上想要进行dfs,矩阵规模稍大就会跪。。还是bfs来的靠谱,除非,将dfs改写成非递归。
class Solution {
public:
int row[50000];
int col[50000];
bool flag;
bool** used;
bool valid(vector<vector<char>> &board,int r,int c){
if(r<board.size() && c<board[0].size() && r>=0 && c>=0 && used[r][c]==false &&board[r][c]=='O'){
used[r][c] = true;
return true;
}
return false;
}
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
void bfs(vector<vector<char>> &board,int r,int c){
int head = 0;
int tail = 0;
row[tail] = r;
col[tail++] = c;
flag = (r>0 && r<board.size()-1 &&c>0 && c<board[0].size()-1);
while(head!=tail){
int r2 = row[head];
int c2 = col[head];
head++;
for(int i=0;i<4;i++){
if(valid(board,r2+dir[i][0],c2+dir[i][1])){
int x = r2+dir[i][0];
int y = c2+dir[i][1];
row[tail] = x;
col[tail++] = y;
flag = flag && x>0 && x<board.size()-1 && y>0 && y<board[0].size()-1;
}
}
}
if(flag){
for(int head=0;head<tail;head++){
board[row[head]][col[head]] = 'X';
}
}
}
void solve(vector<vector<char>> &board) {
int m = board.size();
if(m==0)
return;
int n = board[0].size();
used = new bool*[m];
for(int i=0;i<m;i++){
used[i] = new bool[n];
for(int j=0;j<n;j++)
used[i][j] = false;
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(used[i][j]==true || board[i][j]=='X')
continue;
else{
bfs(board,i,j);
}
}
}
}
};
接下来再贴一份用非递归实现的dfs
class Solution {
public:
bool** used;
bool flag = true;
vector<int> row;
vector<int> col;
int row_stack[50000];
int col_stack[50000];
int top = 0;
int dir[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
bool valid(vector<vector<char>> &board,int r,int c){
return r>=0 && c>=0 && r<board.size() && c<board[0].size() && board[r][c]=='O' && !used[r][c];
}
void dfs(vector<vector<char>> &board,int r,int c){
top=0;
flag = true;
used[r][c] = true;
row_stack[top] = r;
col_stack[top++] = c;
flag = flag && r>0 && r<board.size()-1 && c>0 && c<board[0].size()-1;
row.push_back(r);
col.push_back(c);
while(top>0){
int i = row_stack[--top];
int j = col_stack[top];
for(int k=0;k<4;k++){
int x = i+dir[k][0];
int y = j+dir[k][1];
if(valid(board,x,y)){
used[x][y]=true;
flag = flag && x>0 && x<board.size()-1 && y>0 && y<board[0].size()-1;
row_stack[top] = x;
col_stack[top++] = y;
row.push_back(x);
col.push_back(y);
}
}
}
if(flag){
for(int i=0;i<row.size();i++)
board[row[i]][col[i]]='X';
}
row.clear();
col.clear();
}
void solve(vector<vector<char>> &board) {
int m = board.size();
if(m==0)
return;
int n = board[0].size();
used = new bool*[m];
for(int i=0;i<m;i++){
used[i] = new bool[n];
for(int j=0;j<n;j++)
used[i][j] = false;
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(used[i][j]==true || board[i][j]=='X')
continue;
else{
dfs(board,i,j);
}
}
}
}
};
事实证明,不是dfs差,而是用递归的dfs对栈的需求比较大,如果用迭代来实现的话,和bfs就没有性能上的区别了。。