「这是我参与2022首次更文挑战的第 20 天,活动详情查看:2022首次更文挑战」
题目链接
463. 岛屿的周长 - 力扣(LeetCode) (leetcode-cn.com)
题目描述
给定一个 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 个黄色的边
条件限制
row == grid.length
col == grid[i].length
1 <= row, col <= 100
grid[i][j] 为 0 或 1
题目分析
题目需要我们求湖的周长,但多个单元格相邻的情况下,周长并不会随着单元格的数量线性增长。但是,如果两个相邻的单元格的值存在跳变(即 0->1, 1->0),那么这两个单元格之间的部分就是我们需要求的周长的一部分。
问题就可以简化为,我们从左往右,从上往下遍历二维数组时,判断当前单元格与右侧、下方的坐标值是否跳变。但这种思路,当湖的一部分在数组的四周时,无法通过跳变的方式来判断周长。一个简单的补救措施,就是为这个二维数组包裹一层 0
代码实现
var islandPerimeter = function(grid) {
// 左右补 0
grid.forEach(arr => {
arr.push(0);
arr.unshift(0);
})
let m = grid.length + 2,
n = grid[0].length;
// 上下补 0
let arr = new Array(m).fill(0);
grid.push(arr);
grid.unshift(arr);
let count = 0;
// 横向遍历,纵向遍历,记录跳变
for (let i = 0; i < m - 1; i++) {
for (let j = 0; j < n - 1; j++) {
if (grid[i][j] ^ grid[i + 1][j] == 1) count++;
if (grid[i][j] ^ grid[i ][j+ 1] == 1) count++;
}
}
return count;
};
解法2
同样是依据跳变的思路来计算周长,但是不为数组补一圈 0,直接硬算。
并且,当坐标值为 1 且压在边界上时,判断累加最外边的周长
var islandPerimeter = function(grid) {
let count = 0;
let m = grid.length,
n = grid[0].length;
// 横向遍历,纵向遍历,记录跳变
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (i < m - 1 && grid[i][j] ^ grid[i + 1][j] == 1) count++;
if (j < n - 1 && grid[i][j] ^ grid[i][j + 1] == 1) count++;
if (grid[i][j] == 1) {
if (i == 0) count++;
if (i == m - 1) count++;
if (j == 0) count++;
if (j == n - 1) count++;
}
}
}
return count;
};