给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。
找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。
示例:
X X X X
X O O X
X X O X
X O X X
运行你的函数后,矩阵变为:
X X X X
X X X X
X X X X
X O X X
解释:
被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。
题目分析:这道题和LeetCode200题很类似(200题为找到有多少个岛屿)。因此本题可以分为两个步骤,首先找到被围绕的区间,然后判断被围绕是区间是否位于边界上,如果是则无更改。如果不在边界,则将区域内的点填充为'X'。所以设置regionPos保存每次找到的区域内的点的座标,定义IsRegionNeedFilled来作为标记判断该区域是否有点在边界。
C++代码如下:
class Solution {
vector<vector<bool>> visited;
int d[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
bool inRegion(int x,int y,const vector<vector<char>>& board)
{
return x>=0 && x<board.size() && y>=0 && y<board[0].size();
}
void findConnectedReigion(const vector<vector<char>>& board,const int x,const int y,bool& IsRegionNeedFilled,vector<vector<int>>& regionPos)
{
visited[x][y] = true;
if( x==0 || x == board.size()-1 || y==0 || y == board[0].size()-1)
{
IsRegionNeedFilled = false;
}
vector<int> onePos;
onePos.push_back(x);
onePos.push_back(y);
regionPos.push_back(onePos);
for(int i=0; i < 4; i++)
{
int newx = x + d[i][0];
int newy = y + d[i][1];
// cout<<"newx="<<newx<<"newy="<<newy<<endl;
if( inRegion(newx,newy,board) && board[newx][newy] == 'O' && !visited[newx][newy])
{
// cout<<"inside<<""x="<<newx<<"y="<<newy<<endl;
findConnectedReigion(board,newx,newy,IsRegionNeedFilled,regionPos);
}
}
return;
}
public:
void solve(vector<vector<char>>& board) {
int height = board.size();
if( height == 0) return;
int length = board[0].size();
visited = vector<vector<bool>>(height,vector<bool>(length,false));
for(int i=0; i<height;i++)
{
for(int j=0; j <length; j++)
{
if(board[i][j] == 'O' && visited[i][j] == false)
{//是一个未被发现的区域
vector<vector<int>> regionPos;
bool IsRegionNeedFilled = true;
//find Position
findConnectedReigion(board,i,j,IsRegionNeedFilled,regionPos);
if(IsRegionNeedFilled)
{
//fill
for(int i=0; i<regionPos.size();i++)
{
int x=regionPos[i][0];
int y=regionPos[i][1];
board[x][y] = 'X';
}
}
}
}
}
return;
}
};