About DFS (Depth First Search)
We know that DFS generally searches on a structure such as a tree or a graph, so how do we use it to search in such a grid-like place?
The following grid:
The grid problem is a grid composed of m×n small squares. Each small square is considered to be adjacent to the four squares above, below, left, and right. It is necessary to perform some kind of search on such a grid.
DFS structure
The grid problem is a little more complicated than the structure of the binary tree. To write the DFS on the grid, we must first be familiar with the DFS of the binary tree. The DFS
of the binary tree also includes the front, middle and back order traversal of the binary tree.
The basic structure of binary tree DFS:
void DFS(TreeNode root) {
//判断终止条件
if (root == null) {
return;
}
// 访问两个相邻结点:左子结点、右子结点
DFS(root->left);
DFS(root->right);
}
It is not difficult to see that the DFS of the binary tree has two main points:
- Termination condition judgment
- visit adjacent nodes
Then the grid structure is similar. The grid is centered on a grid and traverses up, down, left, and right: the
grid termination condition
- Beyond Grid Boundaries
- This grid has already been visited (if you do not judge whether the grid has been visited, then there is a risk of an infinite loop)
Grid DFS basic structure:
void dfs(vector<vector<int> grid, int i, int j) {
// 终止条件判断
// 如果坐标超出了网格范围,直接返回
if (终止条件)) {
return;
}
// 如果这个格子不是岛屿,直接返回
if (grid[i][j] != 1) {
return;
}
grid[i][j] = 2; // 将格子标记为「已遍历过」
// 访问上、下、左、右四个相邻结点
dfs(grid, i - 1, j);
dfs(grid, i + 1, j);
dfs(grid, i, j - 1);
dfs(grid, i, j + 1);
}
number of islands
Given a 2D grid consisting of '1' (land) and '0' (water), please count the number of islands in the grid.
Islands are always surrounded by water, and each island can only be formed by connecting horizontally and/or vertically adjacent land.
Also, you can assume that the mesh is surrounded by water on all four sides.
Source: LeetCode (LeetCode) Number of islands
This is a very typical grid problem, and it is actually very simple to solve:
Idea: traverse the grid array in turn, if it is '1', enter the DFS recursion, and traverse its adjacent grids in the recursion, and change the number of the grid to '2', the recursion ends, and continue to traverse the grid array.
The grid array of the function parameter passed into DFS must bequote, so that the islands that have been calculated by the grid can be truly marked, preventing the traversal of the grid array from encountering the same islands, and continuous judgment.
Reference Code:
class Solution {
public:
void DFS(vector<vector<char>>& grid,int i,int j)
{
//终止条件判断
if(i < 0 || i >= grid.size() ||
j < 0 || j >= grid[0].size() || grid[i][j] != '1'){
return;
}
grid[i][j]='2';//已遍历标记
DFS(grid,i+1,j);
DFS(grid,i-1,j);
DFS(grid,i,j+1);
DFS(grid,i,j-1);
}
int numIslands(vector<vector<char>>& grid) {
int sum=0;
for(int i=0;i<grid.size();i++)
{
for(int j=0;j<grid[0].size();j++)
{
if(grid[i][j]=='1')//只有'1'才进入 '0' 与 '2' 都不进入
{
sum++;
DFS(grid,i,j);
}
}
}
return sum;
}
};
perimeter of the island
Given a row x col two-dimensional grid map grid, where: grid[i][j] = 1 means land, grid[i][j] = 0 means water.
The cells in the grid are connected horizontally and vertically (not connected diagonally). The entire grid is completely surrounded by water, but there is exactly one island (or, in other words, an island composed of one or more connected grids representing land).
There is no "lake" in the island ("lake" refers to the water area inside the island and not connected to the water around the island). A lattice is a square with side length 1. The grid is rectangular and must not exceed 100 in width and height. Calculate the perimeter of the island.
Source: Circumference of islands by LeetCode
This question is similar to the above traversal idea, mainly about the judgment of the perimeter:
Circumference Judgment Idea 1:
Circumference Judgment Idea 2:
Reference Code:
class Solution {
public:
int DFS(vector<vector<int>>& grid,int i,int j)
{
//边界+1
if(i<0 || i>=grid.size() || j<0 || j>=grid[0].size())
{
return 1;
}
//'0'海洋+1
if(grid[i][j]==0)
{
return 1;
}
//已遍历过的陆地+0
if(grid[i][j]!=1)
{
return 0;
}
grid[i][j]=2;
return DFS(grid,i-1,j)+
DFS(grid,i+1,j)+
DFS(grid,i,j-1)+
DFS(grid,i,j+1);
}
int islandPerimeter(vector<vector<int>>& grid) {
for(int i=0;i<grid.size();i++)
{
for(int j=0;j<grid[0].size();j++)
{
if(grid[i][j]==1)
{
return DFS(grid,i,j);
}
}
}
return 0;
}
};
The largest area of the island
You are given a binary matrix grid of size mxn.
An island is a combination of some adjacent 1s (representing land). The "adjacent" here requires that two 1s must be adjacent in four horizontal or vertical directions. You can assume that all four edges of the grid are surrounded by zeros (representing water).
The area of an island is the number of cells on the island that have a value of 1.
Calculates and returns the area of the largest island in the grid. If there is no island, the returned area is 0
Source: LeetCode (LeetCode) the maximum area of the island
This question is also a simple question. For this kind of grid DFS problem, as long as the DFS structure is clarified and written according to the gourd, it is actually not difficult.
Idea: Traverse sequentially and iterate the largest area
Reference code:
class Solution {
public:
int DFS(vector<vector<int>>& grid,int i,int j)
{
if(i<0 || i>=grid.size() || j<0 || j>=grid[0].size() || grid[i][j]!=1)
{
return 0;
}
grid[i][j]=2;
return 1+DFS(grid,i+1,j)+
DFS(grid,i-1,j)+
DFS(grid,i,j+1)+
DFS(grid,i,j-1);
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int max=0;
for(int i=0;i<grid.size();i++)
{
for(int j=0;j<grid[0].size();j++)
{
if(grid[i][j]==1)
{
int sum=DFS(grid,i,j);
if(sum>max)
{
max=sum;
}
}
}
}
return max;
}
};