思路:本题是经典的Flood Fill(泛洪)问题,即染色问题 或 颜色填充问题。
这类问题需要把与(i,j)相连接的岛屿都标记上,而不是在其中找到某个序列或者某个值,所以只标记true,不需要进行状态重置。
代码1(修改输入数据):
class Solution { public int numIslands(char[][] grid) { int count = 0; int m = grid.length; if (m == 0) return 0; int n = grid[0].length; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { dfs(grid, i, j); count ++; } } } return count; } private void dfs(char[][] grid, int x, int y) { if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) return; // 如果这个格子不是岛屿,返回。有两种情况:'0'海洋格子。'2'陆地格子(已遍历过) if (grid[x][y] != '1') return; grid[x][y] = '2'; // 避免重复遍历"兜圈子",标记已遍历过的格子 dfs(grid, x - 1, y); dfs(grid, x, y + 1); dfs(grid, x + 1, y); dfs(grid, x, y - 1); } }
代码2(设置vis数组):
class Solution { public int numIslands(char[][] grid) { if (grid == null || grid.length == 0) return 0; int count = 0; int m = grid.length; int n = grid[0].length; boolean[][] visited = new boolean[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1' && !visited[i][j]) { dfs(grid, i, j, visited); count ++; } } } return count; } private void dfs(char[][] grid, int x, int y, boolean[][] visited) { // 越界判断 以及 是否访问过 判断 if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || visited[x][y]) return; if (grid[x][y] == '0') return; visited[x][y] = true; dfs(grid, x - 1, y, visited); dfs(grid, x, y + 1, visited); dfs(grid, x + 1, y, visited); dfs(grid, x, y - 1, visited); } }