1. 程式人生 > >Leetcode題解系列——130. Surrounded Regions(c++版)

Leetcode題解系列——130. Surrounded Regions(c++版)

題目大意:給出一個二維的圖,由X和O兩種字元構成。現在想要將符合條件的O變成X,條件為被X所包圍,且沒有連線的O處在四個邊沿上。

注意點:

  1. 注意判斷搜尋時,會出現越界情況
  2. 當傳入圖為空的處理情況
  3. 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'; } } } } } };