Skip to content

网格图(DFS/BFS/综合应用)

About 1334 wordsAbout 4 min

2025-03-12

分享丨【题单】网格图(DFS/BFS/综合应用)

一、网格图DFS

适用于需要计算联通块个数、大小的题目。

部分题目做法不止一种,也可以用BFS或者并查集解决。

二叉树和网格图递归的区别:

二叉树网格图
递归入口根节点网格图的某个格子
递归方向左子树和右子树一般为左右上下的相邻的格子
递归边界空节点(或者叶子节点)出界、遇到障碍或者已访问

200、岛屿数量(20250728)

Details

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

这里通过灵神的题解来详细解释一下:把访问过的格子插上旗子🚩(Python/Java/C++/C/Go/JS/Rust)

通过题目我们知道就是求岛屿的数量。

假设你是哥伦布。先从左上角开始,把第一个岛上全部插满🚩,这里用2表示。插满旗子后,把答案(岛屿个数)加一。

⚠️注意:在岛上,你只能左右上下走,不能斜着走。

一个岛屿插满之后,继续遍历,然后去到另外一个岛屿。如果没有1,就表示算法结束了,🚩插满了。

如何实现?

一旦我们发现(i,j)(i, j)是1,就从开(i,j)(i, j)始,DFS这个岛,每一步可以往左右上下四个方向走,也就是:

(i,j1),(i,j+1),(i1,j),(i+1,j)(i,j−1),(i,j+1),(i−1,j),(i+1,j)

这四个格子。

如果(i,j)(i, j)出界,或者(i,j)(i, j)是水,或者(i,j)(i, j)已经插上旗子,就不再继续往下递归。

答疑

1、如何理解递归?

递归的思想是,假设你是一家公司的老板,你不需要亲力亲为,而是拆解问题,交给下属去做。对于这题来说,就是从岛屿的某个位置登陆插旗子,然后一分为四,把探索整个岛屿的任务交给其他人去处理,自己只需要处理好第一步就行。

2、我可以先判断grid[i][j]grid[i][j]是否等于1,再判断(i,j)(i,j)是否出界吗?

不行,因为无法确保i,j是否是合法下标。比如i=-1,获取到grid[i][j]grid[i][j]就下标越界了,要先保证下标在范围中,再去获取数据元素。

(在获取数组元素的时候,需要确保下标的合法性)

3、我可以把这行代码grid[i][j]=2grid[i][j]=2写在dfs的最后一行吗?

不行,这样会先执行递归,导致反复横跳,无限递归。比如从点(0,0)(0, 0)到点(0,1)(0, 1),在移动到点(0,0)(0, 0)

4、DFS中能只考虑往右和往下走吗?

不行,比如蚊香型岛屿,在探索的时候必须具备左右上下走的能力。

Java

...

695. 岛屿的最大面积(20250728)

认真解决了第一题,这道题就很容易的解决了,就是给dfs加上返回值。

Java

二、网格图 BFS

适用于需要计算最短距离(最短路)的题目。

三、网格图 0-1 BFS

边权只有 0 和 1 的题目,也可以用 BFS 做。

四、网格图 Dijkstra

图论题单 中的 Dijkstra。

五、综合应用

思考题 1、对于 m 行 n 列的网格图,BFS 的队列最多消耗多少空间?DFS 的递归栈最多消耗多少空间? 2、构造一个网格图,让 DFS 的递归深度尽量大。如果起点是 (0,0) 要如何构造?如果起点是 (i,j) 要如何构造?

Changelog

8/20/25, 11:06 AM
View All Changelog
  • 4c155-Merge branch 'dev1'on

求求了,快滚去学习!!!

求求了求求了,快去学习吧!

【题单】贪心算法

不知道方向的时候,可以多看看书,书会给你指明下一步该干什么,加油!