【LeetCode】每日一题 面试题 16.19. 水域大小

167 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

[面试题 16.19. 水域大小](leetcode.cn/problems/pa…)

你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。

「示例1:」
输入:
[  [0,2,1,0],
  [0,1,0,1],
  [1,1,0,1],
  [0,1,0,1]
]
输出: [1,2,4]
「提示:」
0 < len(land) <= 1000
0 < len(land[i]) <= 1000

解题思路

// 第一种
利用回溯来计算池塘的大小
1.我们发现一个水域,就以该水域为起点,计算该水域周围的水域数量
2.如果我们在水域周围发现新的水域,再以新的水域为起点,计算新的水域周围水域的数量,直到没有水域或者超出界限
3.我们每次计算过的水域,就将他置为陆地,防止再次计算造成死循环
​
最后将结果排序即可
​
// 第二种
广度优先搜索

代码实现

// 第一种
/**
 * @param {number[][]} land
 * @return {number[]}
 */
var pondSizes = function(land) {
    const m = land.length, n = land[0].length
    const res = [], steps = [[0, 1], [0, -1], [1, 0], [1, -1], [1, 1], [-1, 0], [-1, -1], [-1, 1]]
    function getCount(x, y) {
        let count = 1
        for (const [dx, dy] of steps) {
            const nx = x + dx, ny = y + dy
            if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue
            if (!land[nx][ny]) {
                land[nx][ny] = 1
                count += getCount(nx, ny)
            }
        }
        return count
    }
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (!land[i][j]) {
                land[i][j] = 1
                res.push(getCount(i, j))
            }
        }
    }
​
    return res.sort((a, b) => a - b)
};
​
// 第二种
/**
 * @param {number[][]} land
 * @return {number[]}
 */
var pondSizes = function(land) {
    let res = [];
    for (let r=0; r<land.length; r++) {
        for (let c=0; c<land[0].length; c++) {
            if (land[r][c] === 0) {
                let q = [[r,c]];
                let size = 0;
                land[r][c] = -1;
                while (q.length) {
                    let [curR, curC] = q.shift();
                    size += 1;
                    let rr = [curR-1, curR, curR+1];
                    let cc = [curC-1, curC, curC+1];
                    for (let nr of rr) {
                        for (let nc of cc) {
                            if (nr < land.length && nr >= 0) {
                                if (nc < land[0].length && nc >= 0) {
                                    if (!(nr === curR && nc === curC) && land[nr][nc] === 0) {
                                        land[nr][nc] = -1;
                                        q.push([nr, nc]);
                                    }
                                }
                            }
                        }
                    }
                }
                res.push(size);
            }
        }
    }
    res.sort((a,b) => a-b);
    return res;
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;