Here is the idea:

loop the out layer, if found any 'O', do a BFS, mark any 'O' with a temp value, for example 'T'

loop the matrix again, flip 'T' to 'O', and flipt 'O' to 'X'.
public class Solution {
private static char temp = 'T';private class Point { int i; int j; public Point(int i, int j) { this.i = i; this.j = j; } } public void solve(char[][] board) { if (board == null  board.length == 0  board[0] == null  board[0].length == 0) { return; } for (int j = 0; j<board[0].length; j++) { if (board[0][j] == 'O') { mark(board, 0, j); } } for (int i = 1; i<board.length; i++) { if (board[i][board[0].length1] == 'O') { mark(board, i, board[0].length1); } } if (board[0].length > 1) { for (int j = board[0].length2; j>1; j) { if (board[board.length1][j] == 'O') { mark(board, board.length1, j); } } } if (board.length>2) { for (int i = board.length2; i>0; i) { if (board[i][0] == 'O') { mark(board, i, 0); } } } for (int i =0; i<board.length; i++) { for (int j=0; j<board[0].length; j++) { if (board[i][j] == temp) { board[i][j] = 'O'; } else if (board[i][j] == 'O') { board[i][j] = 'X'; } } } } private void mark(char[][] board, int i, int j) { LinkedList<Point> queue = new LinkedList<>(); Point point = new Point(i, j); board[i][j] = temp; queue.add(point); while (!queue.isEmpty() ) { point = queue.remove(); i = point.i; j = point.j; if (i1 >= 0) { if (board[i1][j] == 'O') { board[i1][j] = temp; queue.add(new Point(i1, j)); } } if (i+1 < board.length) { if (board[i+1][j] == 'O') { board[i+1][j] = temp; queue.add(new Point(i+1, j)); } } if (j1 >= 0) { if (board[i][j1] == 'O') { board[i][j1] = temp; queue.add(new Point(i, j1)); } } if (j+1 < board[0].length) { if (board[i][j+1] == 'O') { board[i][j+1] = temp; queue.add(new Point(i, j+1)); } } } }
}