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
算法思路:
1、首先要将给的区域中所有的‘O’元素找到,并放到一个集合中,这里我用到的是map,考虑如下:第一,肯定要把图中给的所有的“O”找到,然后只对这些“O”进行处理,(对“X”处理也没用,还浪费时间),如果只是第一点,只需一个队列就够了;第二,我想能随机的定位到任意元素,并能迅速的修改其值,我用的map定义是
map<char *,node>,(后来想想用set也可以实现),其中node是我自己定义的节点,保存所在位置,其定义如下:
struct node{
int x,y;
node(int i,int j):x(i),y(j){};
};
2、对于map中的元素,利用广度优先搜索,需要一个队列,保存经过的位置,定义为:queue<node> que,另外还需要记住已走过的路径,为了最后从map中将走过的元素删去,再者还需要判断下一个节点是不是走过,所以我用到了set数据结构,节点定义为set<char *> save,之所以定义为char *,是为了最后能快速的修改“O”值为“X”;只有一种情况是不需要修改“O”为“X”的,那就是,广度优先搜索时只要触碰到了边界,与之相连的所有元素,也就是广度优先搜索能搜到的所有元素,都不需要做任何变化,所以加一个flag记录一下就可。只要广度优先能搜索到的,无论需不需要修改值,遍历一遍save中的值,取出,从map中将对应的元素删掉。
struct node{
int x,y;
node(int i,int j):x(i),y(j){};
};
int fang[4][2]={-1,0,1,0,0,-1,0,1};
class Solution{
public:
void solve(vector<vector<char>> &board){
if(board.empty())return;
map<char *,node> store;
map<char *,node>::iterator it;
int r,l;
r=board.size();
l=board[0].size();
for(int i=0;i<r;i++){
for(int j=0;j<l;j++){
if(board[i][j]=='O'){
store.insert(pair<char *,node>(&board[i][j],node(i,j)));
}
}
}
for(;!store.empty();){
set<char *> save;
set<char *>::iterator t;
queue<node> que;
bool flag=false;
it=store.begin();
save.insert(it->first);
que.push(it->second);
while(!que.empty()){
node cur=que.front();
que.pop();
for(int i=0;i<4;i++){
int nx=cur.x+fang[i][0];
int ny=cur.y+fang[i][1];
if(nx<0||ny<0||nx>=r||ny>=l){
flag=true;
continue;
}
if(board[nx][ny]=='X')continue;
t=save.find(&board[nx][ny]);
if(t==save.end()){
save.insert(&board[nx][ny]);
que.push(node(nx,ny));
}
}
}
for(t=save.begin();t!=save.end();t++){
if(!flag){
**t='X';
}
store.erase(*t);
}
}
}
};