Leetcode題解系列——130. Surrounded Regions(c++版)
阿新 • • 發佈:2018-12-15
題目大意:給出一個二維的圖,由X和O兩種字元構成。現在想要將符合條件的O變成X,條件為被X所包圍,且沒有連線的O處在四個邊沿上。
注意點:
- 注意判斷搜尋時,會出現越界情況
- 當傳入圖為空的處理情況
- visited陣列的大小不夠,出現數組越界情況
一.演算法設計
顯然,對於這個二維圖的變化過程,我們可以用寬度搜索的演算法來解決。我們從起點出發,向上下左右四個方向進行搜尋,當搜尋到O時候,將該座標入隊,並且放在一個臨時的vector中(記錄座標,用於後面將O變為X)
每當訪問一個結點,要記得將visited陣列賦值為已訪問狀態。搜尋過程注意拋棄掉一些越界的無效的點,超出左右上下邊界的點。
如果搜尋到X,則不用入隊,繼續迴圈佇列中的元素。 如果搜尋到O,將該結點入隊的同時,向四個方向分別探索檢視是否能繼續入隊。
最後,判斷O的時候還要注意是否為邊界上的O,這裡我使用了一個flag來判斷一個連通的O分量中是否存在邊界O的情況
二.實現程式碼
class Solution {
public:
//四個搜尋方向
int dir[4][2] ={{1,0},{-1,0},{0,1},{0,-1}};
void solve(vector<vector<char>>& board) {
//當傳入圖為空的情況
if(board.empty()) return;
int col = board[0].size();
int row = board.size();
queue<pair<int,int>> q;
int visited[1500][1500] = {0};
vector<pair<int,int>> vp;
bool is_board;
pair<int,int> x;
pair<int,int> temp;
for (int i = 0; i < row; i++){
for ( int j = 0; j < col; j++){
vp.clear();
is_board = false;
if(!visited[i][j]){
pair<int,int> start(i,j);
q.push(start);
//寬度搜索
while(!q.empty()){
temp = q.front();
q.pop();
if(!visited[temp.first][temp.second]){
visited[temp.first][temp.second] = 1;
//訪問到X
if(board[temp.first][temp.second] == 'X') continue;
//訪問到O
else{
vp.push_back(temp);
//判斷是否為邊界O
if(temp.first == 0 || temp.first == row-1
|| temp.second == 0 || temp.second == col-1){
is_board = true;
}
}
//若該結點為O,則向四個方向進行寬度搜索
for(int k = 0; k < 4; k++){
x.first = temp.first + dir[k][0];
x.second = temp.second + dir[k][1];
//超出邊界的結點捨去
if(x.first < 0 || x.first >= row || x.second < 0 || x.second >= col ){
continue;
}
else{
if(board[x.first][x.second] == 'O' && !visited[x.first][x.second]){
q.push(x);
}
}
}
}
}
}
//將非邊界的O賦值為X
if(!is_board){
for(int k = 0; k < vp.size(); k++){
board[vp[k].first][vp[k].second] = 'X';
}
}
}
}
}
};