题目
给定一个 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] 为 0 或 1
思路
今天这题与昨天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;
}
};