题目:
给你一个由 '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
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
核心思路:
循环网格,深度优先遍历每个坐标的四周,注意坐标不要越界,遇到陆地加1,并沉没四周的陆地,这样就不会重复计算.
关键点,从头按顺序遍历网格,会向后修改,这其中默认依赖数据处理顺序了,顺序遍历陆地点,DFS找到当前所属陆地,并下沉当前陆地,再继续遍历
尤其要注意递归的收敛条件,因为存在向四周检索,i、j都存在加减的情况,递减要找左边界,递增要找右边界。按
解:
const numIsLand = (grids) => {
let count = 0;
for (let i = 0; i < grids.length; i++) {
for (let j = 0; j < grids[0].length; j++) {
if (grids[i][j] === '1') {
// 按顺序遍历陆地点,DFS找到当前所属陆地,并下沉当前陆地,再继续遍历
count++;
turnZero(grids, i, j)
}
}
}
return count;
}
function turnZero(arr, i, j) {
// DFS 下沉当前节点所属陆地(相邻四个节点)
if (i < 0 || j < 0 || i >= arr.length || j >= arr[0].length || arr[i][j] === '0') return;
arr[i][j] = '0';
turnZero(arr, i, j + 1)
turnZero(arr, i, j - 1)
turnZero(arr, i + 1, j)
turnZero(arr, i - 1, j)
}
小窍门: 总结了一下,存在一套模板,来解决岛屿类问题:
// 按顺序遍历陆地点,DFS找到当前所属陆地,并下沉当前陆地,再继续遍历
const numIsLand = (grids) => {
for (let i = 0; i < grids.length; i++) {
for (let j = 0; j < grids[0].length; j++) {
if (grids[i][j] === '1') {
xxxxxxxxxxx
dfs(grids, i, j)
}
}
}
return xxxxxxxx;
}
function dfs(arr, i, j) {
// DFS 下沉当前节点所属陆地(相邻四个节点)
if (i < 0 || j < 0 || i >= arr.length || j >= arr[0].length || arr[i][j] === '0' || arr[i][j] === 0) return;
// 此处根据题目具体需求进行操作
arr[i][j] = '0';
// 用于访问当前节点的上下左右的四个节点,进行递归调用
dfs(arr, i, j + 1)
dfs(arr, i, j - 1)
dfs(arr, i + 1, j)
dfs(arr, i - 1, j)
}
———— 前端、Javascript实现、算法、刷题、leetcode