給定一個二維的矩陣,包含 '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;
}
};