文章目录
深度优先搜索 DFS
只要可能,就在图中尽量“深入”,深度优先搜索总是对最近才发现的结点v的出发边进行探索,直到该结点的所有出发边都被发现为止。一旦节点v的所有出发边都被发现,搜索则“回溯”到v的前驱结点,来搜索该前驱结点的出发边。
根据DFS所生成的深度优先森林,可以定义4种边的类型:
- 树边:为深度优先森林种某一棵树的边。如果结点v是因为算法对边(u, v)的探索而首先被发现,则边(u, v)是一条树边
- 后向边B:后向边(u, v)是将结点u连接到其所在深度优先树种一个祖先结点v的边。
- 前向边F:是将结点u连接到其在深度优先树中一个后代结点v的边(u, v);
- 横向边:除上述3种之外的边,可以连接同一棵深度优先树种同一深度的两个结点,也可以连接不同深度优先树种的两个结点。
示例
岛屿数量
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
DFS:
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
void dfs(int i, int j, int m, int n, vector<vector<char> >& grid)
{
if(i < 0 || j < 0 || i >= m || j >= n)
{
// 越界了
return;
}
if(grid[i][j] == '1')
{
grid[i][j] = '0';
dfs(i - 1, j, m, n, grid);
dfs(i + 1, j, m, n, grid);
dfs(i, j + 1, m, n, grid);
dfs(i, j - 1, m, n, grid);
}
}
int solve(vector<vector<char> >& grid) {
// write code here
int m = grid.size();
int n = 0;
int lands = 0;
if(grid.size() > 0)
{
n = grid.at(0).size();
}
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
if(grid[i][j] == '1')
{
lands++;
dfs(i, j, m, n, grid);
}
}
}
return lands;
}
};