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
題意:給出一個2D圖,包含O和X,將被X圍起來的O的區域變爲X
分析:還是一道圖論題。由題可知,若O的連通區域能到達邊緣,那麼這個區域就不變爲X,那麼遍歷圖的四個邊緣,由這些邊緣上的O開始搜索O的區域,將這些O標記爲不變,之後再將剩餘的O變爲X即可。
幾個細節:1、搜索到的不用變化的O先標記爲#,然後將圖中的O變爲X,再將#變爲O,這樣就不需要額外開闢空間了
2、若用遞歸實現dfs,測試數據會造成堆棧溢出,所以只能用迭代方法,我這裏用了bfs搜索
3、bfs時,每次在點入隊時就將其標記爲#,防止重複遍歷,否則會超時
代碼:
class Solution {
private:
int n,m;
void bfs(vector<vector<char>> &bd,int x,int y)
{
bd[x][y] = '#';
queue<pair<int,int> > qu;
qu.push(make_pair(x,y));
while(!qu.empty())
{
pair<int,int> now = qu.front();
qu.pop();
x = now.first;
y = now.second;
if(x>0 && bd[x-1][y]=='O') {qu.push(make_pair(x-1,y));bd[x-1][y] = '#';}
if(x<n-1 && bd[x+1][y]=='O') {qu.push(make_pair(x+1,y));bd[x+1][y] = '#';}
if(y>0 && bd[x][y-1]=='O') {qu.push(make_pair(x,y-1));bd[x][y-1] = '#';}
if(y<m-1 && bd[x][y+1]=='O') {qu.push(make_pair(x,y+1));bd[x][y+1] = '#';}
}
}
void change(vector<vector<char>> &bd,char ori,char cur)
{
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(bd[i][j]==ori)
bd[i][j] = cur;
}
public:
void solve(vector<vector<char>> &board) {
n = board.size();
if(n==0) return;
m = board[0].size();
if(m==0) return;
for(int i=0; i<n; i++)
{
if(board[i][0]=='O') bfs(board,i,0);
if(board[i][m-1]=='O') bfs(board,i,m-1);
}
for(int i=0; i<m; i++)
{
if(board[0][i]=='O') bfs(board,0,i);
if(board[n-1][i]=='O') bfs(board,n-1,i);
}
change(board,'O','X');
change(board,'#','O');
}
};