Flood-Fill. BFS. But there's a trick. If we fill surrounded region directly, extra bookkeeping cost is needed - because we don't know whether that region should be filled or not; but one thing is sure: all regions starting from edges must be the same.
class Solution { public: struct Loc { Loc(int rx, int ry) { x = rx; y = ry; } int x; int y; }; bool isOut(int x, int y, int width, int height) { if (x < 0 || x >= width) return true; if (y < 0 || y >= height) return true; return false; } void goSeed(vector<vector<char>> &board, int x, int y, int width, int height) { queue<Loc> q; q.push(Loc(x, y)); while (!q.empty()) { int x0 = q.front().x; int y0 = q.front().y; if (!isOut(x0 - 1, y0, width, height) && board[y0][x0 - 1] == 'O') { q.push(Loc(x0 - 1, y0)); board[y0][x0 - 1] = '-'; } if (!isOut(x0 + 1, y0, width, height) && board[y0][x0 + 1] == 'O') { q.push(Loc(x0 + 1, y0)); board[y0][x0 + 1] = '-'; } if (!isOut(x0, y0 - 1, width, height) && board[y0 - 1][x0] == 'O') { q.push(Loc(x0, y0 - 1)); board[y0 - 1][x0] = '-'; } if (!isOut(x0, y0 + 1, width, height) && board[y0 + 1][x0] == 'O') { q.push(Loc(x0, y0 + 1)); board[y0 + 1][x0] = '-'; } board[y0][x0] = '-'; q.pop(); } } void solve(vector<vector<char>> &board) { if (board.empty()) return; int height = board.size(); int width = board[0].size(); // Check borders for (int i = 0; i < width; i++) { if (board[0][i] == 'O') goSeed(board, i, 0, width, height); if (board[height - 1][i] == 'O') goSeed(board, i, height - 1, width, height); } for (int i = 1; i < height - 1; i++) { if (board[i][0] == 'O') goSeed(board, 0, i, width, height); if (board[i][width - 1] == 'O') goSeed(board, width - 1, i, width, height); } // for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { if (board[i][j] == '-') board[i][j] = 'O'; else if (board[i][j] == 'O') board[i][j] = 'X'; } } };