池塘计数

114 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情

说在前面

🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是处于什么原因,算法学习需要持续保持,今天让我们一起来看看这一道题目————池塘计数

题目描述

最近的降雨,使田地中的一些地方出现了积水,field[i][j] 表示田地第 i 行 j 列的位置有:

  • 若为 W, 表示该位置为积水
  • 若为 ., 表示该位置为旱地

已知一些相邻的积水形成了若干个池塘,若以 W 为中心的八个方向相邻积水视为同一片池塘。

请返回田地中池塘的数量。

示例 1:

输入: field = [".....W",".W..W.","....W.",".W....","W.WWW.",".W...."]

输出:3

解释:如下图所示,共有 3 个池塘:
image.png

示例 2:

输入: field = ["W....W",".W..W.","..W.W.","W..W..","W.W...",".W...."]

输出:1

解释:如下图所示,共有 1 个池塘:
image.png

提示:

  • 1 <= field.length, field[i].length <= 100
  • field 中仅包含 W 和 .

思路分析

首先我们要先理解一下题意,题目要我们计算田地中池塘的数量,而对于池塘的定义是这样的:已知一些相邻的积水形成了若干个池塘,若以 W 为中心的八个方向相邻积水视为同一片池塘,如下图: image.png

中间的小球可以向四周8个方向行动,也就是说在周围8个方向的格子中有积水的话即可将当前的池塘往外延伸,知道其周围没有积水,所以我们可以找到一处积水,然后将其联通的区域都给找出来并做上标记,计算总共有多少处联通的区域即可,核心代码如下:

  • 遍历找到积水 遍历田地,找到积水
for(let i = 0; i < field.length; i++){
    for(let j = 0; j < field[i].length; j++){
        if(field[i][j] == 'W'){
            res++;
            dfs(i,j);
        }
    }
}
  • 将积水的联调区域做上标记 不断向四周8个方向延伸
const dfs = (x,y)=>{
    if(isOut(x,y)) return;
    const dx = [0,1,-1,0,-1,-1,1,1];
    const dy = [1,0,0,-1,-1,1,-1,1];
    field[x][y] = 'w';
    for(let i = 0; i < 8; i++){
        let nx = x + dx[i],ny = y + dy[i];
        if(!isOut(nx,ny) && field[nx][ny] == 'W'){
            dfs(nx,ny);
        }
    }
}

完整代码如下:

AC代码

/**
 * @param {string[]} field
 * @return {number}
 */
 var lakeCount = function(field) {
    let res = 0;
    for(let i = 0; i < field.length; i++) field[i] = field[i].split('');
    const isOut = (x,y) => {
        return x < 0 || y < 0 || x >= field.length || y >= field[x].length;
    };
    const dfs = (x,y)=>{
        if(isOut(x,y)) return;
        const dx = [0,1,-1,0,-1,-1,1,1];
        const dy = [1,0,0,-1,-1,1,-1,1];
        field[x][y] = 'w';
        for(let i = 0; i < 8; i++){
            let nx = x + dx[i],ny = y + dy[i];
            if(!isOut(nx,ny) && field[nx][ny] == 'W'){
                dfs(nx,ny);
            }
        }
    }
    for(let i = 0; i < field.length; i++){
        for(let j = 0; j < field[i].length; j++){
            if(field[i][j] == 'W'){
                res++;
                dfs(i,j);
            }
        }
    }
    return res;
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。