岛屿数量
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
方法
深度优先遍历
网格问题的基本概念
避免重复遍历:
使用标记
以岛屿问题为例,我们需要在所有值为 1 的陆地格子上做 DFS 遍历。每走过一个陆地格子,就把格子的值改为 2,这样当我们遇到 2 的时候,就知道这是遍历过的格子了。也就是说,每个格子可能取三个值:
- 0 —— 海洋格子
- 1 —— 陆地格子(未遍历过)
- 2 —— 陆地格子(已遍历过)
代码一
统计网格中字符 '1' 出现的次数
class Solution {// 深度优先遍历 参考二叉树的DFS 图/网格 四叉public int numIslands(char[][] grid) {// 定义count 用于统计岛屿的数量int count = 0;// 遍历网格for(int r = 0; r < grid.length; r++){for(int c = 0 ; c < grid[0].length; c++){// 若当前网格的值为“1”,则为陆地,遍历其的上下左右if(grid[r][c] == '1'){// 调用递归函数dfsHelp(grid, r, c);// 统计岛屿数量 由多个陆地组成count ++;}}}// 返回结果return count;}// 递归函数public void dfsHelp(char[][] grid, int row, int column){// 递归出口 防止网格越界if(row < 0 || column < 0 || (row >= 0 && row < grid.length) || (column >= 0 && column < grid[0].length)){return;}// 若网格为海洋 即值为"0"时 或者值为"2"时,也退出if(grid[row][column] == '0'|| grid[row][column] == '2'){return ;}// 将遍历过的陆地1 标记为2grid[row][column] = '2';// 递归遍历dfsHelp(grid, row - 1, column); // 上dfsHelp(grid, row + 1, column); // 下dfsHelp(grid, row, column -1); // 左dfsHelp(grid, row, column +1); // 右}
}
代码二
修改之后的代码
class Solution {// 深度优先遍历 参考二叉树的DFS 图/网格 四叉public int numIslands(char[][] grid) {// 首先对网格进行判空if(grid == null || grid.length == 0){return 0;}// 定义count 用于统计岛屿的数量int count = 0;// 遍历网格for(int r = 0; r < grid.length; r++){for(int c = 0 ; c < grid[0].length; c++){// 若当前网格的值为“1”,则为陆地,遍历其的上下左右if(grid[r][c] == '1'){// 调用递归函数dfsHelp(grid, r, c);// 统计岛屿数量 由多个陆地组成count ++;}}}// 返回结果return count;}// 递归函数public void dfsHelp(char[][] grid, int row, int column){// 递归出口 防止网格越界if(row < 0 || column < 0 || row >= grid.length || column >= grid[0].length){return;}// 若网格为海洋 即值为"0"时 或者值为"2"时,即值不等于1时 也退出if(grid[row][column] != '1'){return ;}// 将遍历过的陆地1 标记为2grid[row][column] = '2';// 递归遍历dfsHelp(grid, row - 1, column); // 上dfsHelp(grid, row + 1, column); // 下dfsHelp(grid, row, column -1); // 左dfsHelp(grid, row, column +1); // 右}
}