[算法题解详细]DFS解力扣463岛屿的周长

题目

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
示例1
在这里插入图片描述

输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16
解释:它的周长是上面图片中的 16 个黄色的边

示例2

输入:grid = [[1]]
输出:4

示例3

输入:grid = [[1,0]]
输出:4

提示

 1. row == grid.length
 2. col == grid[i].length
 3. 1 <= row, col <= 100
 4. grid[i][j]01

思路

今天这题与昨天DFS解力扣130被围绕的区域这一题很类似,首先我们阅读题干找关键信息
1.grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域
这时我们知道这个矩阵代表着一张地图,大小是row x col

2.水平和垂直 方向相连(对角线方向不相连)
规定了水域或者陆地相连的方向

3.整个网格被水完全包围,但其中恰好有一个岛屿
注意此题中只有一个岛屿

因此这一题意思就是让我们求由1组成的这个形状的周长,这里因为这块陆地我们并不能确认位置,所以我们需要一次遍历来进行dfs,并且在进入dfs之后,如果当前点是等于1(也就是是陆地)的话,就把它的值改成另一个比如2,然后在上下左右四个方向继续进行搜索,具体怎么做我们直接看代码

代码

首先看主函数,我们用双循环来遍历这个矩阵的每一个点
对于每一个点,如果入口的点值为1则我们加入这个点的值,反之不加入

class Solution {
    
    
	int m, n;
	int islandPerimeter(vector<vector<int>>& grid) {
    
    
        m = int(grid.size());
        n = int(grid[0].size());
        int ans = 0;
        for(int i = 0; i < m; i++) {
    
    
            for(int j = 0; j < n; j++) {
    
    
                if(grid[i][j] == 1) {
    
    
                    ans += dfs(grid, i, j);
                }
            }
        }
        return ans;
    }
}

dfs的出口条件应当是坐标不符合规则或者是当前搜索点值为0(意味着搜索到了陆地的边界)

int dfs(vector<vector<int>>& grid, int x, int y) {
    
    
	if(x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) {
    
    
	            return 1;
	}
}

返回1的原因是因为搜索到水域时,陆地的这条边也要算进周长里,所以返回1
接着我们需要判断当前点是否已经访问过,如果访问过,我们直接返回0

int dfs(vector<vector<int>>& grid, int x, int y) {
    
    
		if(x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) {
    
    
		            return 1;
		}
		if(grid[x][y] == 2) {
    
    
			return 0;
		}	
}

在所有判断条件结束后,我们需要对当前访问的点进行一个标记,将值改为2,方便我们后续搜索的判断
然后最后是对当前点的上下左右进行搜索

int dfs(vector<vector<int>>& grid, int x, int y) {
    
    
        if(x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) {
    
    
            return 1;
        }
        if(grid[x][y] == 2) {
    
    
            return 0;
        }
        grid[x][y] = 2;
        return dfs(grid, x + 1, y) + dfs(grid, x - 1, y) + dfs(grid, x, y + 1) + dfs(grid, x, y - 1);
}

然后我们将代码总结到一起
完整代码:

class Solution {
    
    
public:
    int m, n;
    int dfs(vector<vector<int>>& grid, int x, int y) {
    
    
        if(x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) {
    
    
            return 1;
        }
        if(grid[x][y] == 2) {
    
    
            return 0;
        }
        grid[x][y] = 2;
        return dfs(grid, x + 1, y) + dfs(grid, x - 1, y) + dfs(grid, x, y + 1) + dfs(grid, x, y - 1);
    }
    int islandPerimeter(vector<vector<int>>& grid) {
    
    
        m = int(grid.size());
        n = int(grid[0].size());
        int ans = 0;
        for(int i = 0; i < m; i++) {
    
    
            for(int j = 0; j < n; j++) {
    
    
                if(grid[i][j] == 1) {
    
    
                    ans += dfs(grid, i, j);
                }
            }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_61607810/article/details/121056504