描述
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。
岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
例如:
输入
[
[1,1,0,0,0],
[0,1,0,1,1],
[0,0,0,1,1],
[0,0,0,0,0],
[0,0,1,1,1]
]
对应的输出为3
(注:存储的01数据其实是字符’0’,‘1’)
题目给出的是一个二维数组,可以把其想象成一个平面图,把总数组里面的索引想象成y轴, 把子数组想象成x轴,那么每一个值都有一个坐标。我们要探索海洋中的岛屿,值为1的为陆地,值为0的为海洋,相邻的陆地为同一块岛屿,我们需要探索每一个点。当我们到达陆地之后,需要判断其上下左右是否还是陆地,如果是陆地,那么进入该陆地继续判断。同时标记已探索过的陆地,避免重复探索,当遇到的陆地是我们已经探索过的,就不探索该陆地,直接跳过。
1,新建统计变量number和has表
const has = {};
let number = 0;
2,遍历这个二维数组
grid.forEach((item, y) => {
item.forEach((value, x) => {
})
})
3, 判断当前值是否为陆地
const keys = `${y}-${x}`;
if (value === '1' && !has[keys]) {}
4,只有是陆地我们才进入其中探索
has[keys] = true;
number += 1;
5, 新建一个回调让其执行边界探索, 当边界还存在其他陆地就进入其中,并标记。
function dfs(x, y, grid) {
if (!Array.isArray(grid[y])) {
return;
};
const key = `${y}-${x}`;
const yLen = grid.length;
const xLen = grid[y].length;
if (grid[y][x] === '0') {
return;
};
if (grid[y][x] === '1') {
has[key] = true;
};
if ((x + 1) < xLen && grid[y][x + 1] === '1' && !has[`${y}-${x + 1}`]) {
dfs(x + 1, y, grid);
};
if ((y + 1) < yLen && grid[y + 1][x] === '1' && !has[`${y + 1}-${x}`]) {
dfs(x, y + 1, grid);
};
if ((x - 1) >= 0 && grid[y][x - 1] === '1' && !has[`${y}-${x - 1}`]) {
dfs(x - 1, y, grid);
}
if ((y - 1) >= 0 && grid[y - 1][x] === '1' && !has[`${y - 1}-${x}`]) {
dfs(x, y - 1, grid);
}
}
全部代码
/**
* 判断岛屿数量
* @param grid string字符串型二维数组
* @return int整型
*/
function solve( grid ) {
// write code here
const has = {};
let number = 0;
grid.forEach((item, y) => {
item.forEach((value, x) => {
const keys = `${y}-${x}`;
if (value === '1' && !has[keys]) {
has[keys] = true;
number += 1;
dfs(x, y, grid);
function dfs(x, y, grid) {
if (!Array.isArray(grid[y])) {
return;
};
const key = `${y}-${x}`;
const yLen = grid.length;
const xLen = grid[y].length;
if (grid[y][x] === '0') {
return;
};
if (grid[y][x] === '1') {
has[key] = true;
};
if ((x + 1) < xLen && grid[y][x + 1] === '1' && !has[`${y}-${x + 1}`]) {
dfs(x + 1, y, grid);
};
if ((y + 1) < yLen && grid[y + 1][x] === '1' && !has[`${y + 1}-${x}`]) {
dfs(x, y + 1, grid);
};
if ((x - 1) >= 0 && grid[y][x - 1] === '1' && !has[`${y}-${x - 1}`]) {
dfs(x - 1, y, grid);
}
if ((y - 1) >= 0 && grid[y - 1][x] === '1' && !has[`${y - 1}-${x}`]) {
dfs(x, y - 1, grid);
}
}
}
})
})
return number;
}
module.exports = {
solve : solve
};
这样就可以通过啦。
我们还可以统计岛屿的大小,海洋坐标以便还原出整个地图。
新建一个map 和计数器 count, 分为海洋和陆地。
const map = {
land: {},
ocean: {},
};
let count = 0;
当遍历到不是陆地时,记录海洋坐标。
if (value === '0'){
map.ocean[keys] = '0';
}
当到陆地后,count 开始计数。
if (value === '1' && !has[keys]) {
has[keys] = true;
number += 1;
count += 1;
map.land[count] = {
region: {
},
size: 0,
}
在探索过程中,如果,到达陆地陆地大小加一,同时记录陆地坐标。
map.land[count].region[key] = '1',
map.land[count].size += 1;
/**
* 判断岛屿数量
* @param grid string字符串型二维数组
* @return int整型
*/
function solve( grid ) {
// write code here
const has = {};
const map = {
land: {},
ocean: {},
};
let count = 0;
let number = 0;
grid.forEach((item, y) => {
item.forEach((value, x) => {
const keys = `${y}-${x}`;
if (value === '1' && !has[keys]) {
has[keys] = true;
number += 1;
count += 1;
map.land[count] = {
region: {
},
size: 0,
}
dfs(x, y, grid);
function dfs(x, y, grid) {
if (!Array.isArray(grid[y])) {
return;
};
const key = `${y}-${x}`;
const yLen = grid.length;
const xLen = grid[y].length;
if (grid[y][x] === '0') {
return;
};
if (grid[y][x] === '1') {
has[key] = true;
map.land[count].region[key] = '1',
map.land[count].size += 1;
};
if ((x + 1) < xLen && grid[y][x + 1] === '1' && !has[`${y}-${x + 1}`]) {
dfs(x + 1, y, grid);
};
if ((y + 1) < yLen && grid[y + 1][x] === '1' && !has[`${y + 1}-${x}`]) {
dfs(x, y + 1, grid);
};
if ((x - 1) >= 0 && grid[y][x - 1] === '1' && !has[`${y}-${x - 1}`]) {
dfs(x - 1, y, grid);
}
if ((y - 1) >= 0 && grid[y - 1][x] === '1' && !has[`${y - 1}-${x}`]) {
dfs(x, y - 1, grid);
}
}
}
if (value === '0'){
map.ocean[keys] = '0';
}
})
})
return number;
}
module.exports = {
solve : solve
};