前言:锻炼自己的思想,规范自己的编程思路。
问题:
你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。
示例:(放代码里面)
输入:
[
[0,2,1,0],
[0,1,0,1],
[1,1,0,1],
[0,1,0,1]
]
输出: [1,2,4]
思路:
这段代码是用来计算矩阵中所有池塘的大小,并将其从小到大排序的。函数使用了深度优先搜索(DFS)算法。
pondSizes 函数接受一个二维数组 land 作为输入,表示一片土地的整数矩阵。
如果 land 为空或长度为0,则返回空数组。
然后定义一个空数组 res 来存储结果。然后使用两个嵌套循环遍历整个矩阵。如果当前位置的值为0,则表示这是一个水域,调用 dfs 函数来计算这个池塘的大小,并将结果添加到 res 数组中。
最后,对 res 数组进行排序并返回结果。
dfs 函数接受四个参数:land 矩阵、当前位置的行索引 i、当前位置的列索引 j 和一个计数器 count。如果当前位置越界或不是水域,则返回0。
然后将计数器加1,并将当前位置的值设为-1,表示已经访问过。然后递归地调用 dfs 函数来搜索当前位置周围的8个方向,并将返回值累加到计数器中。
最后,就会返回计数器的值,表示当前池塘的大小。
基于上述思考,代码如下:
/**
* @param {number[][]} land
* @return {number[]}
*/
var pondSizes = function(land) {
if (!land || land.length === 0) return [];
let res = [];
for (let i = 0; i < land.length; i++) {
for (let j = 0; j < land[0].length; j++) {
if (land[i][j] === 0) {
res.push(dfs(land, i, j));
}
}
}
return res.sort((a, b) => a - b);
}
function dfs(land, i, j) {
if (i < 0 || i >= land.length || j < 0 || j >= land[0].length || land[i][j] !== 0) return 0;
let count = 1;
land[i][j] = -1;
count += dfs(land, i + 1, j);
count += dfs(land, i - 1, j);
count += dfs(land, i, j + 1);
count += dfs(land, i, j - 1);
count += dfs(land, i + 1, j + 1);
count += dfs(land, i - 1, j - 1);
count += dfs(land, i - 1, j + 1);
count += dfs(land, i + 1, j - 1);
return count;
}
执行结果如下图: