面试知识库

200. 岛屿数量#

👋 今天我们要聊的这道题,在谷歌、微软、字节的面试中经常出现。它不只是考察代码能力,更是在测试你对搜索算法的理解深度。

🎯 从一张旧地图说起#

想象一下,你正在研究一张古老的藏宝图:

  • 蓝色的海水中散落着若干座岛屿
  • 每座岛屿都由若干块相连的陆地组成
  • 你需要数清楚到底有多少座独立的岛屿

这不就是今天要解决的算法题吗?

问题描述#

题目目标#

给你一个由字符 '1'(陆地)和 '0'(水)组成的二维网格 grid ,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平或垂直方向上相邻的陆地连接形成。

示例 1#

输入:

grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]
text

输出: 1 网格示意:

1 1 1 1 0
1 1 0 1 0
1 1 0 0 0
0 0 0 0 0
text

说明: 图示把输入结构和输出结果并排展开后,会更容易直接看清题目的变化过程。

💡 问题的本质#

LeetCode 200题”岛屿数量”是这样描述的:

输入一个由 '1'(陆地)和 '0'(水)组成的二维网格
要求计算网格中岛屿的数量(岛屿是由相邻陆地单元组成的区域)

示例:
输入:
[
  ['1','1','0','0','0'],
  ['1','1','0','0','0'],
  ['0','0','1','0','0'],
  ['0','0','0','1','1']
]
输出:3
plaintext

🤔 看起来简单?等等,这里有几个关键点:

  1. 什么算”相邻”?(上下左右四个方向)
  2. 如何避免重复计算同一个岛屿?
  3. 如何高效地探索整个地图?

🎨 绘画给我们的启发#

想象你在给这张地图上色:

  • 发现一块陆地,就用红色笔把它涂掉
  • 顺着这块陆地,把所有相连的陆地都涂红
  • 完成后,又发现新的未涂色的陆地,换个颜色继续…

每换一次颜色,就代表发现了一座新岛屿!这就是深度优先搜索(DFS)的思想。

⚡ 代码实现:深度优先搜索#

🔍 解法要点解析#

就像探索一座未知的岛屿:

  1. 发现陆地就开始探索
  2. 把探索过的地方标记一下(防止迷路)
  3. 向四个方向继续探索
  4. 直到这座岛屿探索完毕
  5. 寻找下一座未探索的岛屿

📊 复杂度分析#

时间复杂度:O(M × N)

  • M 和 N 是地图的行数和列数
  • 每个格子最多被访问一次

空间复杂度:O(M × N)

  • 最坏情况:整个地图都是陆地
  • 递归调用栈的深度可能达到 M × N

🎯 面试官最爱追问#

  1. Q:如何处理超大地图? A:可以考虑分块处理,或使用广度优先搜索(BFS)减少栈空间

  2. Q:如果不能修改输入数组呢? A:可以用额外的visited数组记录访问状态

  3. Q:如何计算最大岛屿面积? A:只需在DFS时统计每个岛屿的面积即可

💡 举一反三#

这个解题思路还可以用在:

  • 封闭岛屿的数量
  • 最大岛屿面积
  • 岛屿的周长
  • 不同岛屿的数量

🎁 思考题#

如果要求每座岛屿必须是正方形才计数,怎么修改代码?

示例:
1 1 1    这个算一座岛
1 1 1    (3×3的正方形)
1 1 1

1 1 1    这个不算
1 1 1    (非正方形)
1 1 0
plaintext

如果你知道答案?请在评论区留言~