携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第32天,点击查看活动详情
说在前面
🎈不知道大家对于算法的学习是一个怎样的心态呢?为了面试还是因为兴趣?不管是处于什么原因,算法学习需要持续保持,今天让我们一起来看看这一道题目————
池塘计数。
题目描述
最近的降雨,使田地中的一些地方出现了积水,field[i][j] 表示田地第 i 行 j 列的位置有:
- 若为
W, 表示该位置为积水; - 若为
., 表示该位置为旱地。
已知一些相邻的积水形成了若干个池塘,若以 W 为中心的八个方向相邻积水视为同一片池塘。
请返回田地中池塘的数量。
示例 1:
输入:
field = [".....W",".W..W.","....W.",".W....","W.WWW.",".W...."]输出:
3解释:如下图所示,共有 3 个池塘:
示例 2:
输入:
field = ["W....W",".W..W.","..W.W.","W..W..","W.W...",".W...."]输出:
1解释:如下图所示,共有 1 个池塘:
提示:
1 <= field.length, field[i].length <= 100field中仅包含W和.
思路分析
首先我们要先理解一下题意,题目要我们计算田地中池塘的数量,而对于池塘的定义是这样的:已知一些相邻的积水形成了若干个池塘,若以 W 为中心的八个方向相邻积水视为同一片池塘,如下图:
中间的小球可以向四周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前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。