思路1:DFS
如果把X看作海水,O看作陆地,被海水包围的就是岛屿。没有被海水包围的陆地,与边界有连通,就不是岛屿。判断是否是岛屿比较困难,问题转化为先找出非岛屿(凡是与边界有联系的O),即对边界上的 O 特殊处理。根据题意,四个边的 0 以及与其相邻的 0 都不能被替换为X,因此从边界向里面扩展。解决步骤为:
1)把四周有 0 的地方都替换为 “#”,在四周进行floodfill算法(染色)。
2)再从头到尾遍历矩阵,把 0 换成 X, 把“#”换成0.
思路2:BFS
思路3:并查集
代码1:
class Solution { public void solve(char[][] board) { if (board == null || board.length == 0) return; int m = board.length, n = board[0].length; // Step1:对边界上的O特殊处理,进行FloodFill // 难点:如何只遍历边界 // for (int i = 0; i < m; i++) { // for (int j = 0; j < n; j++) { // if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { // if (board[i][j] == 'O') { // dfs(board, i, j); // } // } // } // } // 遍历第一列 和 最后一列 for (int i = 0; i < m; i++) { if (board[i][0] == 'O') dfs(board, i, 0); if (board[i][n-1] == 'O') dfs(board, i, n-1); } // 遍历第一行 和 最后一行 for (int i = 1; i < n - 1; i++) { if (board[0][i] == 'O') dfs(board, 0, i); if (board[m-1][i] == 'O') dfs(board, m-1, i); } // Step2:重新遍历矩阵,直接替换 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (board[i][j] == 'O') { board[i][j] = 'X'; }else if (board[i][j] == '#') { board[i][j] = 'O'; } } } } // 思路同岛屿问题 private void dfs(char[][] board, int x, int y) { if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) return; if (board[x][y] != 'O') return; board[x][y] = '#'; dfs(board, x - 1, y); dfs(board, x, y + 1); dfs(board, x + 1, y); dfs(board, x, y - 1); } }