PracticeNeetCode ↗LeetCode ↗
Given an m × n board of 'X' and 'O', flip every 'O' region to 'X' if it's completely enclosed by 'X'. A region is not captured if any of its cells touch the border.
'#') protects the safe cells from being flipped, then gets converted back to 'O' at the end.'O' on the border, marking each connected 'O' reached with '#'.'O' (unmarked, so fully enclosed) to 'X'.'#' back to 'O' to restore the safe regions.Time: O(rows · cols) — Space: O(rows · cols)
def solve(board: list[list[str]]) -> None:
if not board:
return
rows, cols = len(board), len(board[0])
def dfs(r: int, c: int) -> None:
if r < 0 or r >= rows or c < 0 or c >= cols or board[r][c] != "O":
return
board[r][c] = "#"
for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
dfs(r + dr, c + dc)
for r in range(rows):
dfs(r, 0)
dfs(r, cols - 1)
for c in range(cols):
dfs(0, c)
dfs(rows - 1, c)
for r in range(rows):
for c in range(cols):
if board[r][c] == "O":
board[r][c] = "X"
elif board[r][c] == "#":
board[r][c] = "O"How the solution above works, piece by piece.
dfs from every border cell turns each connected O into # ("safe").O were never reached from the border, so flip them to X; turn # back into O.# in the board itself avoids a separate visited set.Running it on an example board: