给你一个由 '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
提示:
这题需要用到 DFS 算法遍历矩阵中每个元素,DFS 代码框架如下:
// 二叉树遍历框架
func traverse(TreeNode root) {
traverse(root.Left)
traverse(root.Right)
}
// 二维矩阵遍历框架
func dfs(grid [][]int, i, j int, visited [][]bool) {
m, n := len(grid), len(grid[0])
if i < 0 || j < 0 || i >= m || j >= n {
// 超出索引边界
return
}
if visited[i][j] {
// 已遍历过 (i, j)
return
}
// 进入节点 (i, j)
visited[i][j] = true
dfs(grid, i-1, j, visited) // 上
dfs(grid, i+1, j, visited) // 下
dfs(grid, i, j-1, visited) // 左
dfs(grid, i, j+1, visited) // 右
}
用 DFS 算法解决岛屿题目是最常见的,每次遇到一个岛屿中的陆地,就用DFS把这个岛屿淹掉(避免维护 visited 数组),因为 dfs 函数遍历到 '0' 的位置会直接返回,所以只要把经过的位置都设置为 '0',就可以起到不走回头路的作用。
func numIslands(grid [][]byte) int {
m, n := len(grid), len(grid[0])
nums := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == '1' { // 发现了岛屿
nums++
// 淹没此岛屿,目的是可以避免记录 visited 数组
dfs(grid, i, j)
}
}
}
return nums
}
func dfs(grid [][]byte, i, j int) {
m, n := len(grid), len(grid[0])
if i < 0 || j < 0 || i >= m || j >= n {
return
}
if grid[i][j] == '0' {
return
}
// 淹没此岛屿
grid[i][j] = '0'
dfs(grid, i-1, j) // 上
dfs(grid, i+1, j) // 下
dfs(grid, i, j-1) // 左
dfs(grid, i, j+1) // 右
}