一、题目
二、深度优先搜索
1、算法思想
- 深度优先搜索(depth-first seach,DFS)是一种用于解决图搜索问题的优先搜索/遍历算法。
- 图搜索问题是在具有节点和边的图结构中寻找特定目标的问题,通常需要找到从起始节点到目标节点的路径或者确定是否存在这样的路径。
- 基本的思路就是:从起始节点开始,沿着一条路径一直走到底,直到不能再走为止;然后回溯到上一个节点,再走其他可能的路径,直到所有的路径都遍历过为止。
- 从上述思路可以知道:当遍历完一条路径以后需要回溯到上一个节点,而且通常需要返回一些值,因此DFS函数中需要使用先入后出的栈 或者 与栈等价的递归 实现。
2、算法模板
int/void/... dfs(输入:一般为初始节点)
1、记录该节点对应的值,具体题目具体分析;
2、一般会增加一个变量记录是否搜索过该节点;
3、开始进行遍历,可能会有不同的方向(通常单独建立一个变量表示搜索方向):
搜索到下一个节点,判断该节点是否满足一定的条件(具体问题,具体分析):
满足条件,则会调用dfs函数进行递归(注意递归一定要有边界条件,来结束递归)
4、返回结果:return 某个值
三、解法
1、岛屿的最大面积
1)整体思路:将网格中的每个节点作为初始节点(如果是陆地在进入dfs,否则没必要进入),以四个方向进行遍历实现深度优先搜索;
2)dfs函数输入为初始节点(x, y),定义两个vector dx和dy表示四个方向,以及一个与grid同维度的g来表示每个节点是否已被搜索过;
3)dfs函数中:定义area表示该节点是否为陆地,是陆地为1,否则为0。然后记录该节点是否被搜索过,被搜索过变为0。开始遍历节点:如果该节点的位置在网格内,且值为1,则area += dfs(x, y)。
class Solution {
public:
int m, n;
vector<vector<int>> g;
vector<int> dx = {-1, 1, 0, 0};
vector<int> dy = {0, 0, -1, 1};
int dfs(int x, int y){
int area = 1;
g[x][y] = 0;
for (int k = 0; k < 4; k++){
int a = x + dx[k];
int b = y + dy[k];
if (a >= 0 && a < m && b >= 0 && b < n && g[a][b]){
area += dfs(a, b);
}
}
return area;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
m = grid.size();
n = grid[0].size();
g = grid;
int res = 0;
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (g[i][j]){
res = max(res, dfs(i, j));
}
}
}
return res;
}
};
2、岛屿数量
与上一题类似,由于要计算岛屿数量,dfs遍历完所有路径以后,返回值改为1即可
class Solution {
public:
int m, n;
vector<vector<char>> g;
vector<int> dx = {-1, 1, 0, 0};
vector<int> dy = {0, 0, -1, 1};
int dfs(int x, int y){
g[x][y] = '0';
for (int k = 0; k < 4; k++){
int a = x + dx[k];
int b = y + dy[k];
if (a >= 0 && a < m && b >= 0 && b < n && g[a][b] == '1'){
dfs(a, b);
}
}
return 1;
}
int numIslands(vector<vector<char>>& grid) {
m = grid.size();
n = grid[0].size();
g = grid;
int res = 0;
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (g[i][j] == '1'){
res += dfs(i, j);
}
}
}
return res;
}
};