🧠
Brute Force (Check Each 'O' Region Separately)
💡 This approach exists to build intuition by directly checking each 'O' region for boundary connection, even though it's inefficient. It helps understand the problem's core challenge.
Intuition
For each 'O', explore its connected region to see if it touches the boundary. If not, flip all 'O's in that region to 'X'.
Algorithm
- Iterate over each cell in the board.
- When an 'O' is found, perform DFS/BFS to find all connected 'O's.
- Check if any 'O' in this region touches the boundary.
- If no boundary 'O' found, flip all 'O's in this region to 'X'.
💡 The challenge is managing repeated searches and ensuring you don't flip regions connected to the boundary.
from collections import deque
def solve(board):
if not board or not board[0]:
return
m, n = len(board), len(board[0])
visited = [[False]*n for _ in range(m)]
def bfs(r, c):
queue = deque([(r, c)])
region = [(r, c)]
visited[r][c] = True
touches_boundary = r == 0 or r == m-1 or c == 0 or c == n-1
while queue:
x, y = queue.popleft()
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
nx, ny = x+dx, y+dy
if 0 <= nx < m and 0 <= ny < n and not visited[nx][ny] and board[nx][ny] == 'O':
visited[nx][ny] = True
queue.append((nx, ny))
region.append((nx, ny))
if nx == 0 or nx == m-1 or ny == 0 or ny == n-1:
touches_boundary = True
return region, touches_boundary
for i in range(m):
for j in range(n):
if board[i][j] == 'O' and not visited[i][j]:
region, touches_boundary = bfs(i, j)
if not touches_boundary:
for x, y in region:
board[x][y] = 'X'
# Example usage:
if __name__ == '__main__':
board = [
['X','X','X','X'],
['X','O','O','X'],
['X','X','O','X'],
['X','O','X','X']
]
solve(board)
for row in board:
print(row)
Line Notes
if not board or not board[0]:Check for empty input to avoid errors
visited = [[False]*n for _ in range(m)]Track visited cells to avoid repeated work
def bfs(r, c):Define BFS to explore connected 'O' region
touches_boundary = r == 0 or r == m-1 or c == 0 or c == n-1Initialize boundary touch flag
if nx == 0 or nx == m-1 or ny == 0 or ny == n-1:Update flag if region touches boundary
if board[i][j] == 'O' and not visited[i][j]:Start BFS only on unvisited 'O's
if not touches_boundary:Flip region only if not connected to boundary
import java.util.*;
public class SurroundedRegions {
public void solve(char[][] board) {
if (board == null || board.length == 0) return;
int m = board.length, n = board[0].length;
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O' && !visited[i][j]) {
List<int[]> region = new ArrayList<>();
boolean touchesBoundary = bfs(board, visited, i, j, region);
if (!touchesBoundary) {
for (int[] cell : region) {
board[cell[0]][cell[1]] = 'X';
}
}
}
}
}
}
private boolean bfs(char[][] board, boolean[][] visited, int r, int c, List<int[]> region) {
int m = board.length, n = board[0].length;
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{r, c});
visited[r][c] = true;
region.add(new int[]{r, c});
boolean touchesBoundary = r == 0 || r == m - 1 || c == 0 || c == n - 1;
int[][] directions = {{-1,0},{1,0},{0,-1},{0,1}};
while (!queue.isEmpty()) {
int[] curr = queue.poll();
for (int[] d : directions) {
int nr = curr[0] + d[0], nc = curr[1] + d[1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n && !visited[nr][nc] && board[nr][nc] == 'O') {
visited[nr][nc] = true;
queue.offer(new int[]{nr, nc});
region.add(new int[]{nr, nc});
if (nr == 0 || nr == m - 1 || nc == 0 || nc == n - 1) {
touchesBoundary = true;
}
}
}
}
return touchesBoundary;
}
// Driver code
public static void main(String[] args) {
SurroundedRegions sr = new SurroundedRegions();
char[][] board = {
{'X','X','X','X'},
{'X','O','O','X'},
{'X','X','O','X'},
{'X','O','X','X'}
};
sr.solve(board);
for (char[] row : board) {
System.out.println(Arrays.toString(row));
}
}
}
Line Notes
if (board == null || board.length == 0) return;Guard clause for empty input
boolean[][] visited = new boolean[m][n];Track visited cells to prevent reprocessing
boolean touchesBoundary = r == 0 || r == m - 1 || c == 0 || c == n - 1;Initialize boundary touch flag
if (board[i][j] == 'O' && !visited[i][j])Start BFS only on unvisited 'O's
visited[nr][nc] = true;Mark cells visited when added to queue
if (nr == 0 || nr == m - 1 || nc == 0 || nc == n - 1)Update flag if region touches boundary
if (!touchesBoundary)Flip region only if not connected to boundary
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
class Solution {
public:
void solve(vector<vector<char>>& board) {
if (board.empty() || board[0].empty()) return;
int m = board.size(), n = board[0].size();
vector<vector<bool>> visited(m, vector<bool>(n, false));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (board[i][j] == 'O' && !visited[i][j]) {
vector<pair<int,int>> region;
bool touchesBoundary = bfs(board, visited, i, j, region);
if (!touchesBoundary) {
for (auto& cell : region) {
board[cell.first][cell.second] = 'X';
}
}
}
}
}
}
private:
bool bfs(vector<vector<char>>& board, vector<vector<bool>>& visited, int r, int c, vector<pair<int,int>>& region) {
int m = board.size(), n = board[0].size();
queue<pair<int,int>> q;
q.push({r, c});
visited[r][c] = true;
region.push_back({r, c});
bool touchesBoundary = (r == 0 || r == m - 1 || c == 0 || c == n - 1);
int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
while (!q.empty()) {
auto [x, y] = q.front(); q.pop();
for (auto& d : dirs) {
int nx = x + d[0], ny = y + d[1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && board[nx][ny] == 'O') {
visited[nx][ny] = true;
q.push({nx, ny});
region.push_back({nx, ny});
if (nx == 0 || nx == m - 1 || ny == 0 || ny == n - 1) {
touchesBoundary = true;
}
}
}
}
return touchesBoundary;
}
};
int main() {
Solution sol;
vector<vector<char>> board = {
{'X','X','X','X'},
{'X','O','O','X'},
{'X','X','O','X'},
{'X','O','X','X'}
};
sol.solve(board);
for (auto& row : board) {
for (char c : row) cout << c << ' ';
cout << '\n';
}
return 0;
}
Line Notes
if (board.empty() || board[0].empty()) return;Check for empty input to avoid errors
vector<vector<bool>> visited(m, vector<bool>(n, false));Track visited cells to avoid repeated work
bool touchesBoundary = (r == 0 || r == m - 1 || c == 0 || c == n - 1);Initialize boundary touch flag
if (board[i][j] == 'O' && !visited[i][j])Start BFS only on unvisited 'O's
visited[nx][ny] = true;Mark cells visited when added to queue
if (nx == 0 || nx == m - 1 || ny == 0 || ny == n - 1)Update flag if region touches boundary
if (!touchesBoundary)Flip region only if not connected to boundary
function solve(board) {
if (!board || board.length === 0) return;
const m = board.length, n = board[0].length;
const visited = Array.from({length: m}, () => Array(n).fill(false));
function bfs(r, c) {
const queue = [[r, c]];
const region = [[r, c]];
visited[r][c] = true;
let touchesBoundary = r === 0 || r === m - 1 || c === 0 || c === n - 1;
while (queue.length) {
const [x, y] = queue.shift();
for (const [dx, dy] of [[-1,0],[1,0],[0,-1],[0,1]]) {
const nx = x + dx, ny = y + dy;
if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && board[nx][ny] === 'O') {
visited[nx][ny] = true;
queue.push([nx, ny]);
region.push([nx, ny]);
if (nx === 0 || nx === m - 1 || ny === 0 || ny === n - 1) {
touchesBoundary = true;
}
}
}
}
return [region, touchesBoundary];
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (board[i][j] === 'O' && !visited[i][j]) {
const [region, touchesBoundary] = bfs(i, j);
if (!touchesBoundary) {
for (const [x, y] of region) {
board[x][y] = 'X';
}
}
}
}
}
}
// Example usage:
const board = [
['X','X','X','X'],
['X','O','O','X'],
['X','X','O','X'],
['X','O','X','X']
];
solve(board);
console.log(board);
Line Notes
if (!board || board.length === 0) return;Guard clause for empty input
const visited = Array.from({length: m}, () => Array(n).fill(false));Track visited cells to avoid repeated work
let touchesBoundary = r === 0 || r === m - 1 || c === 0 || c === n - 1;Initialize boundary touch flag
if (board[i][j] === 'O' && !visited[i][j])Start BFS only on unvisited 'O's
visited[nx][ny] = true;Mark cells visited when added to queue
if (nx === 0 || nx === m - 1 || ny === 0 || ny === n - 1)Update flag if region touches boundary
if (!touchesBoundary)Flip region only if not connected to boundary
TimeO(m*n*(m+n))
SpaceO(m*n)
For each 'O', BFS explores connected region which can be large; repeated BFS leads to high complexity.
💡 For a 10x10 board, this could mean up to 100 BFS traversals, each visiting many cells, causing slow performance.
Interview Verdict: TLE / Inefficient for large boards
This approach is too slow for large inputs but helps understand the problem and is a good starting point.