大家好今天给大家分享下一道 LeetCode 中等难度 的题目200. 岛屿数量
题目
给你一个由
'1'
(陆地)和'0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1: 输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] 输出:1 示例 2: 输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] 输出:3
分析
1.只能水平方向访问 或者垂直方法访问
2.1与1之间相连,0不能访问
3.返回数字
解法
1.dfs
2.bfs
解法一:DFS
思路
1.因为是二维解决所以通过两层遍历每个节点
2.如果碰到'1'代表可以走,所以进行dfs遍历,同时代表了遇到了一个岛屿 count++
3.dfs 深度优先遍历
1.首先判断是否在矩阵中 isGrid(i,j)
2.在判断是否是访问过的 set.has(i+'_'+j)(因为访问的时候可能会访问重复的节点)
3.访问过的节点加入set中
4.是个方法访问周边的节点
*/
var numIslands = function (grid) {
// 添加set 防止重复访问
const set = new Set();
let res = 0;
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[0].length; j++) {
// 只有为‘1’并且set中不存在的值才能进入dfs访问
if (grid[i][j] === "1" && !set.has(i + "_" + j)) {
visitGridElementDfs(grid, i, j);
res++;
}
}
}
return res;
// 判断是否在矩阵中
function inGrid(i, j) {
return i > -1 && i < grid.length && j > -1 && j < grid[0].length;
}
function visitGridElementDfs(grid, i, j) {
// 不在矩阵中返回
if (!inGrid(i, j)) {
return;
}
// 遇到‘0’返回
if (grid[i][j] === "0") {
return;
}
// 遇到访问过的节点返回
if (set.has(i + "_" + j)) {
return;
}
set.add(i + "_" + j);
// 向上访问
visitGridElementDfs(grid, i + 1, j);
// 向下访问
visitGridElementDfs(grid, i - 1, j);
// 向左边访问
visitGridElementDfs(grid, i, j + 1);
// 向右边访问
visitGridElementDfs(grid, i, j - 1);
}
};
/* 复杂度
时间 O(MN) M为行数 N为列数,
空间 O(MN)
*/
解法二:BFS
思路
1.因为是二维解决所以通过两层遍历每个节点
2.如果碰到'1'代表可以走,所以进行dfs遍历,同时代表了遇到了一个岛屿 count++
3.bfs 广度优先遍历
1.首先把起点放入一个队列中
2.取出队列首部元素,然后判断
1.是否在 矩阵中
2.是否遇到了‘0’
3.是否访问过
3.如果上述条件都不满足,则把这个元素各个方法的元素都放入队列中
*/
var numIslands = function (grid) {
const seen = new Set();
let count = 0;
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[0].length; j++) {
// 只有为‘1’并且set中不存在的值才能进入dfs访问
if (grid[i][j] === "1" && !seen.has(i + "_" + j)) {
visitGridElementBfs(grid, i, j);
count++;
}
}
}
return count;
// 判断是否在矩阵中
function inGrid(i, j) {
return i > -1 && i < grid.length && j > -1 && j < grid[0].length;
}
function visitGridElementBfs(grid, i, j) {
const list = [];
list.push([i, j]);
while (list.length) {
const cur = list.shift();
(i = cur[0]), (j = cur[1]);
if (!inGrid(i, j)) continue;
if (grid[i][j] === "0") continue;
if (seen.has(i + "_" + j)) continue;
seen.add(i + "_" + j);
list.push([i + 1, j]);
list.push([i - 1, j]);
list.push([i, j + 1]);
list.push([i, j - 1]);
}
}
};
/* 复杂度
时间 O(MN) M为行数 N为列数
空间 O(MN)
*/
总结
这道题考察的是Graph的应用,如何使用DFS 来BFS 遍历节点
大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com