力扣刷题:水域大小

143 阅读2分钟

前言:锻炼自己的思想,规范自己的编程思路。

问题:

你有一个用于表示一片土地的整数矩阵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;
}

执行结果如下图:

image-20230622231721615.png

image-20230622231655918.png