LeetCode OJ:Surrounded Regions

Surrounded Regions

  Total Accepted: 3163  Total Submissions: 22161 My Submissions

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);
			}
		}
		
	}
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值