一、DFS
1、LeetCode No1254
1、题目中要求封闭岛屿的数目,即有多少片被1包围的0。我们首先想到边界上的0是肯定不会被1包围的,连着边界上的0肯定也是不会被1包围的,所以要去除边界上的0和连着边界的0的干扰。因此遍历四个边界,边界上的每个点向下去做深度搜索,若是0的话改成1,排除干扰。
2、此时二维数组中剩下的0肯定都是被1包围的了,遍历这个二维数组,遇到0,封闭岛数量加1
同时深度遍历,把连着的0变成1.
3、深度遍历(DFS):传入遍历到的点,上下左右做深度搜索,直到越界或者不满足条件()该点为水域),是陆地的点改成水域,这要就可以不用维护visited数组(用于记录已经遍历过的点)。
技巧总结:
①边界可以排除干扰
②岛问题可以改变已经遍历过的点的值,避免重复遍历
③可以用一个visited数组记录遍历过的点避免重复遍历
④DFS深度遍历 上下左右深度遍历,不满足条件的return,满足条件的改值。
⑤从边界开始DFS,而不是从里面开始到边界
class Solution {
public int closedIsland(int[][] grid) {
//把边界上的0变成1 ,连着边界的0变成1 剩下的连着的0就是一个封闭岛屿
int rows = grid.length;
int col = grid[0].length;
int res = 0;
for (int i = 0; i < rows; i++) {
dfs(grid, i, 0);
dfs(grid, i, col - 1);
}
for (int i = 0; i < col; i++) {
dfs(grid, 0, i);
dfs(grid, rows - 1, i);
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < col; j++) {
if (grid[i][j] == 0) {
res++;
dfs(grid, i, j);
}
}
}
return res;
}
public void dfs(int[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length) {
return;
}
if (grid[i][j] == 1) {
return;
}
grid[i][j] = 1;
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
}
2、LeetCode No130
此题和Leecode No1254类似,1254题是要记录封闭岛数量,因此边界陆地被更改无影响,中间记录过一次导数量后,这边导都要改值,避免重复遍历。
本题要返回二维数组,因此返回时边界的值不能被改变,可以用一个特殊的字符来标识(边界开始深度遍历来改值),最后改回来。由于不用计数,所以中间的都是封闭岛,可以直接遍历改值。
此题还可以用并查集来做,见并查集小节。
二、并查集
并查集技巧:
主函数中判断需要合并的两个样本(边界先合并,思考是上下左右找合并,还是左上还是啥),调用并查集模板UnionFind中的union方法进行合并或动态初始化上下左右找,满足条件的合并(条件:不越界,有size,代表节点不同)。
UnionFind模板中:
①样本包成一个圈,样本指向自己样本可以用数组或者坐标的下标表示 int[][] parents或map 为了小挂大,记录圈的大小以及控制是否被初始化过 int[] size; 为了结构扁平化 int[] help; 初始的圈数量(样本数量 或0)
②初始化
静态初始化:样本是本身,传入数组长度初始化 样本是坐标,坐标转换成数组下标初始化
动态初始化:给一个条件,传入动态初始化UnionFind中connet方法中初始化(若该样本没有被初始化过),上下左右看有没有可以合并的(越界、不可以连的size0,已经连过的代表节点一样),输出一个结果,构造方法只初始化大小。
③union方法
不在一个圈的合并 代表节点不是一个
有的需要判断,size为0的不合并
size小的挂size大的
④findParent方法
找代表节点的方法,help[]中的都指向代表节点,使结构扁平化。
1、LeetCode No547
1、其中题目中给的二维数组isConnected[i][j]表示i城市和j城市相连。则本题的样本就是各个城市,i城市和j城市包成一个圈。
2、主函数中判断满足条件需要合并成一个圈的两个样本。调用并查集模板UnionFind中的union方法进行合并。
2、LeetCode No130
此题在DFS章节使用DSF解,也可以使用并查集来解