使用dfs遍历网格,每发现一个未访问的'1'就启动一次dfs将整个连通陆地区域标记为'0'并计数加1,最终返回岛屿总数;核心在于外层找起点、dfs负责淹没连通块,边界检查与原地标记确保正确性与空间最优。

直接用 DFS 遍历每个陆地并“淹没”整块连通区域,每启动一次 DFS 就代表发现一座新岛屿。
核心逻辑:找起点 + 淹没连通块
不是逐个数 '1',而是每次遇到未处理的 '1',就把它和所有上下左右能连上的 '1' 全部标记为 '0'——这个过程就是一次 DFS。计数器只在发现新起点时加 1。
- 外层双循环遍历每个格子,只关心是否为 '1'
- 遇到 '1',count++,立刻调用 dfs 把整个岛屿“清空”
- dfs 内部不做计数,只负责把当前连通区域全改写成 '0'
DFS 递归实现的关键细节
递归函数要先做边界和状态检查,再修改当前格子,最后递归四个方向。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 终止条件必须写全:越界(i = grid.length、j = grid[0].length)或非陆地(grid[i][j] == '0')
- 标记动作放在检查通过后、递归调用前:grid[i][j] = '0'
- 四个方向递归顺序无关紧要,但推荐按上、下、左、右或下、上、右、左等固定顺序,便于调试
避免常见错误的写法要点
看似简单,但容易在边界判断、标记时机、空输入处理上出错。
- 开头必须判空:if (grid == null || grid.length == 0) return 0;
- 不要在 dfs 里重复检查 grid[i][j] == '1' —— 外层已确保进入 dfs 时是 '1',而 dfs 内部靠终止条件拦截非法访问
- 不要用额外 visited 数组:直接改原 grid 是空间最优解,且不影响正确性
- 递归调用前不加 if 判断——那是终止条件该做的事;重复判断会导致漏访或栈溢出
完整可运行的 Java 版本
以下代码已通过力扣 200 题验证:
public int numIslands(char[][] grid) {if (grid == null || grid.length == 0) return 0;
int count = 0;
for (int i = 0; i for (int j = 0; j if (grid[i][j] == '1') {
count++;
dfs(grid, i, j);
}
}
}
return count;
}
private void dfs(char[][] grid, int i, int j) {
if (i = grid.length || j = grid[0].length || grid[i][j] == '0') return;
grid[i][j] = '0';
dfs(grid, i - 1, j);
dfs(grid, i + 1, j);
dfs(grid, i, j - 1);
dfs(grid, i, j + 1);
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










