dfs和bfs都是分为两个函数
主函数负责寻找每一个没被访问过且是陆地的点,
前面的函数负责的是,把这个点相连的陆地都放问一遍。
也就是,主函数每找到一个符合要求的点,就是找到了一块陆地。
之所以「主函数每找一个合规点 = 一块陆地」,是因为 dfs 把整块都标成了 visited ,主函数后面扫到同块里的其他点时,它们已经被访问过,不会再触发新的 flood。于是每块陆地只被数一次------这就是 count++ 放主函数、不放 dfs 的原因。
水流问题:

是 遍历每个点,然后看这个点 能不能同时到达第一组边界和第二组边界。
第一个方法的 dfs,输出的是一句话:「从起点 (x,y) 出发,水顺着能流到的所有格子」 ------也就是 visited 图上被标成 true 的那一片连通区域。
具体拆开说:
dfs(grid, visited, x, y)跑完之后,visited[i][j] == true的含义是:存在一条从(x,y)到(i,j)的「高度不增」路径(每步走到 ≤ 自己的邻居,水往低处流)。- 换句话说,
visited= 这个点肚子里的水能漫到的全部地盘。 - 然后
isResult拿这张图去问两件事:- 这片地盘有没有碰到上边或左边 ?→
isFirst - 这片地盘有没有碰到下边或右边 ?→
isSecond - 都碰到 → 说明
(x,y)的水能同时流进两组边界(两片海),返回true。
- 这片地盘有没有碰到上边或左边 ?→
优化
那么我们可以 反过来想,从第一组边界上的节点 逆流而上,将遍历过的节点都标记上。
同样从第二组边界的边上节点 逆流而上,将遍历过的节点也标记上。
然后两方都标记过的节点就是既可以流向第一组边界也可以流向第二组边界的节点。
从第一组边界边上节点出发,如图: (图中并没有把所有遍历的方向都画出来,只画关键部分)

,意思是cong第一边界和第二边界分别深搜,往高处走,走过的就在各自的visit图上标注1,如果两个图都标1了就代表这个点是我们要找的。
方法一是,每个点一副自己流过的01图,然后去对比是否在第一区和二区都有为1的点。第二个是全局一共就维护两幅图,一个是一区能到达的点,一个是二区能到达的点,如果两个有重叠的就输出
- 方法一:N 张图,每张图自问「我碰没碰到边界」 → 每个点各算各的,重复且慢(O((nm)²))。
- 方法二:2 张图,每张图自问「边界能碰到谁」 → 全局算一次,取交集,干净且快(O(nm))。