您的位置:首页 > 其它

leetCode-Surrounded Regions DFS与BFS解法

2015-04-27 16:57 369 查看
问题描述

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

思路

可以先把与边界连通的O区域全部替换为Z,则剩下的O区域则肯定不与边界连通,可以直接替换为X,从而最后再将Z替换为原来的O。

其中的关键就在第一步,在边界上找到某个O后,通过BFS或者DFS将所有与该O连通的O替换为Z。

void fill_DFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
if(board[i][j] == target)
{
stack<pair<int ,int>>s;
s.push(make_pair(i,j));
board[i][j] = c;
while(!s.empty())
{
int x = s.top().first;
int y = s.top().second;
//board[x][y] = c;
s.pop();
if(x > 0 && board[x-1][y] == target) { board[x-1][y] = c ; s.push(make_pair(x-1,y));}
if(x < board.size()-1 && board[x+1][y] == target) {board[x+1][y] =c; s.push(make_pair(x+1,y));}
if(y > 0 && board[x][y-1] == target)  {board[x][y-1] = c;s.push(make_pair(x,y-1));}
if(y < board[0].size()-1 && board[x][y+1] == target) {board[x][y+1] = c ;s.push(make_pair(x,y+1));}

}
}
}

void fill_BFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
if(board[i][j] == target)
{
queue<pair<int ,int>>q;
q.push(make_pair(i,j));
board[i][j] = c;

while(!q.empty())
{
int x = q.front().first;
int y = q.front().second;
// board[x][y] = c;
q.pop();
if(x > 0 && board[x-1][y] == target){ board[x-1][y] = c ; q.push(make_pair(x-1,y));}
if(x < board.size()-1 && board[x+1][y] == target) {board[x+1][y] =c; q.push(make_pair(x+1,y));}
if(y > 0 && board[x][y-1] == target) {board[x][y-1] = c;q.push(make_pair(x,y-1));}
if(y < board[0].size()-1 && board[x][y+1] == target) {board[x][y+1] = c ;q.push(make_pair(x,y+1));}

}
}
}

class Solution {
public:
void solve(vector<vector<char>> &board) {
if(board.size() == 0) return ;
for(int i = 0 ; i < board.size(); ++i)
{
if(board[i][0] == 'O') fill_DFS(board,i,0,'O','Z');
if(board[i][board[0].size()-1] == 'O') fill_DFS(board,i,board[0].size()-1,'O','Z');
}

for(int i = 0 ; i < board[0].size() ;++i)
{
if(board[0][i] == 'O') fill_DFS(board,0,i,'O','Z');
if(board[board.size()-1][i] == 'O') fill_DFS(board,board.size()-1,i,'O','Z');
}

for(int i = 0; i<board.size() ;++i)
{
for(int j = 0; j < board[0].size() ;++j)
{
if(board[i][j] == 'O') board[i][j] = 'X';
else if(board[i][j] == 'Z') board[i][j] = 'O';
}
}
}};


注意:BFS与DFS均要记录元素是否已经被访问。!!!

一开始,BFS代码如下,怎么也跑不出结果,通过调试发现代码陷入了循环之中:

void fill_BFS(vector<vector<char>> &board , int i , int j , char target , char c)
{
if(board[i][j] == target)
{
queue<pair<int ,int>>q;
q.push(make_pair(i,j));

while(!q.empty())
{
int x = q.front().first;
int y = q.front().second;
board[x][y] = c; //注意这里,在出队列时才替换元素导致入队列时出现大量重复
q.pop();
if (x > 0 && board[x - 1][y] == target) q.push(make_pair(x - 1, y));
if (x < board.size() - 1 && board[x + 1][y] == target) q.push(make_pair(x + 1, y));
if (y > 0 && board[x][y - 1] == target) q.push(make_pair(x, y - 1));
if (y < board[0].size() - 1 && board[x][y + 1] == target) q.push(make_pair(x, y + 1));

}
}
}


原因就是不是在入队列前就已经把’O’ 变为’Z’, 导致不能判断相邻的元素是否已经入队列,造成队列中包含大量的重复元素,使得效率极低。

所以DFS与BFS均应该利用一个额外的数组或者在原有数据上使用某种标记,来标志该元素已经被访问过。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: