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 X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
Solution:
We use backtracking to identify the elements not surrounded by 'X' and we mark those with a temporal symbol ('$'). The elements not surrounded by 'X' means that exists a path of elements 'O' to a border. So we start the backtracking algorithm with the boarders.The last thing is replacing the temporal element by 'O' and the rest elements to 'X'.
We have used a non-recursive implementation of backtracking, using a stack. This implementation is more efficient in space. For instance, this algorithm in its recursive implementation does not pass the test due to overflowing the stack.
public class Solution {
final static char TEMPORARY_MARKED ='$';
final static char TO_CAPTURE = 'O';
final static char CAPTURED ='X';
public void solve(char[][] board) {
if(board.length ==0 )
return;
int numberRows = board.length;
int numberCols = board[0].length;
for(int col=0; col<numberCols; col++)
{
mark(board,0,col);
mark(board,numberRows-1,col);
}
for(int row=0; row<numberRows; row++)
{
mark(board,row,0);
mark(board,row,numberCols-1);
}
for(int row=0; row<numberRows; row++)
{
for(int col=0; col<numberCols; col++)
{
board[row][col]= board[row][col]==TEMPORARY_MARKED ? TO_CAPTURE : CAPTURED;
}
}
}
public void mark(char[][] board, int row, int col)
{
int position = row*board[0].length + col;
ArrayDeque<Integer> stack = new ArrayDeque<Integer>();
stack.push(position);
while(!stack.isEmpty())
{
position = stack.pop();
row = position / board[0].length;
col = position % board[0].length;
if( board[row][col] != TO_CAPTURE)
continue;
board[row][col] = TEMPORARY_MARKED;
if (row>0)
stack.push((row-1)*board[0].length + col);
if (col>0)
stack.push(row*board[0].length + col-1);
if (row<board.length-1 )
stack.push((row+1)*board[0].length + col);
if (col<board[0].length-1 )
stack.push(row*board[0].length + col+1);
}
}
}



