天机阁

200. 岛屿数量

2022-07-28 · 3 min read
LeetCode

给你一个由 '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'

题解

这题需要用到 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) // 右
}