標籤:leetcode 演算法 面試
【題目】
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 XX O O XX X O XX O X X
After running your function, the board should be:
X X X XX X X XX X X XX O X X
【題意】
給定一個二維矩陣,由‘X‘和‘O‘填充,本題要求把那些被‘X‘包圍的‘O‘替換為‘X‘。注意這裡的包圍是指四周完全包圍。如果某片‘O‘地區觸及了矩陣的邊界,則這片地區就不算被‘X‘包圍。
【思路】
我們只需要先把觸及到邊界的‘O‘地區全部替換成另一個字母, 比如‘M‘。矩陣中剩下的‘O‘地區就肯定是被包圍的了。
然後,我們掃描矩陣把‘O‘替換成‘X‘, 把‘M‘替換回‘O‘即可
地區的遍曆,使用DFS或BFS
DFS要使用遞迴,當矩陣很大的時候容易逾時
所以本題使用BFS
【代碼】
class Solution {public: void O2M(vector<vector<char> >&board, int i, int j){ //從board[i][j]開始,遍曆'O'地區,把'O'替換成'M' int rows=board.size(); int cols=board[0].size(); queue<int> qe; qe.push(i*cols+j); board[i][j]='M'; while(!qe.empty()){ int pos = qe.front(); qe.pop(); i=pos/cols; j=pos%cols; //判斷上方 if(i-1>=0 && board[i-1][j]=='O'){ board[i-1][j]='M'; //注意在將相鄰元素填到隊列中時,需要將它標記為以訪問,否則以後在確定其他節點的'O'相鄰位置時,很有可能又把這個節點加入到隊列中。造成死迴圈。 qe.push((i-1)*cols + j); } //判斷下方 if(i+1<rows && board[i+1][j]=='O'){ board[i+1][j]='M'; qe.push((i+1)*cols + j); } //判斷左方 if(j-1>=0 && board[i][j-1]=='O'){ board[i][j-1]='M'; qe.push(i*cols + j-1); } //判斷右方 if(j+1<cols && board[i][j+1]=='O'){ board[i][j+1]='M'; qe.push(i*cols + j+1); } } } void solve(vector<vector<char>> &board) { int rows=board.size(); if(rows==0)return; int cols=board[0].size(); if(cols==0)return; //把臨邊的'O'地區替換成'M' //上邊 for(int j=0; j<cols; j++){ if(board[0][j]=='O')O2M(board, 0, j); } //下邊 for(int j=0; j<cols; j++){ if(board[rows-1][j]=='O')O2M(board, rows-1, j); } //左邊 for(int i=0; i<rows; i++){ if(board[i][0]=='O')O2M(board, i, 0); } //右邊 for(int i=0; i<rows; i++){ if(board[i][cols-1]=='O')O2M(board, i, cols-1); } //掃描矩陣,把O替換成X, 把M替換成O for(int i=0; i<rows; i++){ for(int j=0; j<cols; j++){ if(board[i][j]=='O')board[i][j]='X'; else if(board[i][j]=='M')board[i][j]='O'; } } }};