1. Per-Component DFS with Boundary Reachability Flag
Intuition
Isolate each connected component of Os. If no cell in the component touches row 0, m-1 or col 0, n-1, flip all cells in the recorded component to X.
Algorithm
- Step 1: Maintain a global visited[m][n] boolean array.
- Step 2: Iterate over every cell (r, c). If board[r][c] ==
Oand not visited, start component search. - Step 3: Collect all cells in the connected component and check if any cell lies on the boundary.
- Step 4: If touchesBoundary == false, iterate through all cells in the component and flip board[r][c] =
X.
Per-Component DFS with Boundary Reachability Flag Trace
2 of 2 questions left todayEncounter 'O' at (1,1)
Encounter O at (1,1). Launch DFS with reachesBoundary = false.
#include <iostream>#include <vector> class Solution { int m, n; int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; void dfs(int r, int c, std::vector<std::vector<char>>& board, std::vector<std::vector<bool>>& visited, std::vector<std::pair<int, int>>& component, bool& touchesBorder) { visited[r][c] = true; component.push_back({r, c}); if (r == 0 || r == m - 1 || c == 0 || c == n - 1) { touchesBorder = true; } for (auto& d : dirs) { int nr = r + d[0], nc = c + d[1]; if (nr >= 0 && nr < m && nc >= 0 && nc < n && board[nr][nc] == 'O' && !visited[nr][nc]) { dfs(nr, nc, board, visited, component, touchesBorder); } } } public: void solve(std::vector<std::vector<char>>& board) { if (board.empty() || board[0].empty()) return; m = board.size(); n = board[0].size(); std::vector<std::vector<bool>> visited(m, std::vector<bool>(n, false)); for (int r = 0; r < m; ++r) { for (int c = 0; c < n; ++c) { if (board[r][c] == 'O' && !visited[r][c]) { std::vector<std::pair<int, int>> component; bool touchesBorder = false; dfs(r, c, board, visited, component, touchesBorder); if (!touchesBorder) { for (auto& cell : component) { board[cell.first][cell.second] = 'X'; } } } } } }}; int main() { Solution solver; std::vector<std::vector<char>> board = { {'X', 'X', 'X', 'X'}, {'X', 'O', 'O', 'X'}, {'X', 'X', 'O', 'X'}, {'X', 'O', 'X', 'X'} }; solver.solve(board); for (const auto& row : board) { for (char c : row) std::cout << c << " "; std::cout << ""; } return 0;}Time & Space Complexity
- Time complexity:
O(M * N)— Time complexity for Per-Component DFS with Boundary Reachability Flag. - Space complexity:
O(M * N)— Space complexity for Per-Component DFS with Boundary Reachability Flag.
Why Brute Force Doesn't Scale:
For N = 105, quadratic O(N2) approaches require ~1010 operations, exceeding the standard 1-second CPU budget.
The optimal approach processes N elements in a single or logarithmic pass, completing in under 10ms with minimal memory footprint.