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 X X O O X X X O X X O X XAfter running your function, the board should be:
X X X X X X X X X X X X X O X X
BFS, but the following code runs in Time Limited Excced problem.
We should find all the ‘O’ cells that are connected to the ‘O’ cells on the boundary. These ‘O’ cells are survived and not captured.
Use Breadth First Search
Time Limit Exceed sulution.
//What should I return if board is NULL? //Will the size of the board be very large? More than 2^32? //It's just like the rules in Go.(Wei qi) //Is the board always be a rectangular? //BFS class Cell{ public: int row, column; Cell(int i, int j): row(i), column(j){} }; class Solution { public: void solve(vector<vector<char>>& board) { //extreme cases if(board.size() <= 1) return ; //ordinary cases, traverse the board, find all 'O' cells for(size_t i = 0; i < board.size(); i++){ for(size_t j = 0; j < board[0].size(); j++){ if(board[i][j] == 'O'){ BFS(board, i, j); } } } restoreBoard(board); } void BFS(vector<vector<char>> & board, int row, int column){ int rowSize = board.size(); int columnSize = board[0].size(); queue<Cell> q; q.push(Cell(row, column)); board[row][column] = 'V'; //visited while(!q.empty()){ Cell cell = q.front(); q.pop(); row = cell.row; column = cell.column; for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ int offsetRow = i * 2 - 1; int offsetColumn = j * 2 - 1; int nrow = row + offsetRow; int ncolumn = column + offsetColumn; //out of boundary if(nrow < 0 || nrow >= board.size() || ncolumn < 0 || ncolumn > board[0].size()){ markAsSurvive(board); return ; } if(board[row][column] == 'V'){ //visited continue; } if(board[nrow][ncolumn] == 'O'){ q.push(Cell(nrow, ncolumn)); board[nrow][ncolumn] = 'V'; } } } } markAsCaptured(board); } void markAsSurvive(vector<vector<char>> & board){ for(size_t i = 0; i < board.size(); i++){ for(size_t j = 0; j < board[0].size(); j++){ if(board[i][j] == 'V') board[i][j] = 'S'; } } } void markAsCaptured(vector<vector<char>> & board){ for(size_t i = 0; i < board.size(); i++){ for(size_t j = 0; j < board[0].size(); j++){ if(board[i][j] == 'V') board[i][j] = 'X'; } } } void restoreBoard(vector<vector<char>> & board){ for(size_t i = 0; i < board.size(); i++){ for(size_t j = 0; j < board[0].size(); j++){ if(board[i][j] == 'S') board[i][j] = 'O'; } } } };
AC solution
We don’t need a hash table to record visited cells, manipulate the board, mark visited cell as ‘S’ is an ingenious method.
class Cell{ public: int row, column; Cell(int row, int column):row(row), column(column){} }; class Solution { public: void solve(vector<vector<char>>& board) { //extreme cases if(board.size() == 0) return; if(board.size() <= 1 || board[0].size() <= 1) return; //traverse boundary cells for(size_t i = 0; i < board.size(); i++){ BFS(board, i, 0); //left boundary BFS(board, i, board[0].size() - 1); //right boundary } for(size_t i = 0; i < board[0].size(); i++){ BFS(board, 0, i); //top boundary BFS(board, board.size() - 1, i); //bottom boundary } markSurviveAsO(board); } void BFS(vector<vector<char>> & board, int row, int column){ queue<Cell> q; int dict[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}}; //direction if(board[row][column] != 'O') return ; q.push(Cell(row, column)); board[row][column] = 'S'; //survive while(!q.empty()){ row = q.front().row; column = q.front().column; q.pop(); for(int i = 0; i < 4; i++){ int nrow = row + dict[i][0]; int ncolumn = column + dict[i][1]; if(nrow < 0 || nrow >= board.size() || ncolumn < 0 || ncolumn >= board[0].size()){ //out of boundary continue; } if(board[nrow][ncolumn] == 'O'){ board[nrow][ncolumn] = 'S'; q.push(Cell(nrow, ncolumn)); } } } } void markSurviveAsO(vector<vector<char>> & board){ for(size_t i = 0; i < board.size(); i++){ for(size_t j = 0; j < board[0].size(); j++){ char c = board[i][j]; if(c == 'S') board[i][j] = 'O'; else board[i][j] = 'X'; } } } };