题目来源:力扣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
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
的值为'0'
或'1'
思路:将二维网格看成一个无向图,竖直或水平相邻的 1 之间有边相连。为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。最终岛屿的数量就是进行深度优先搜索的次数。
解析:
-
DFS 函数
dfs
- 参数:
grid
代表二维网格,i
和j
代表当前网格位置的行列索引。 - 检查当前索引是否超出边界:如果
i
或j
小于 0,或者大于等于网格的大小,则直接返回。 - 检查当前位置是否为水(
'0'
):如果是,则直接返回。 - 将当前位置标记为已访问(变为
'0'
)。 - 递归调用
dfs
函数,分别访问上下左右四个相邻的位置。
- 参数:
-
计算岛屿的数量函数
numIslands
- 参数:
grid
代表二维网格。 - 初始化岛屿计数器
c
为 0。 - 使用双层循环遍历网格的每个位置。
- 如果找到一个新的土地(
'1'
),调用dfs
函数进行标记,并将岛屿计数器c
加 1。 - 返回岛屿的总数
c
。
- 参数:
-
主函数
main
- 声明并初始化两个示例网格
grid1
和grid2
。 - 分别调用
numIslands
函数计算两个网格中的岛屿数量,并输出结果。
- 声明并初始化两个示例网格
C++
#include<bits/stdc++.h>
using namespace std;
// 深度优先搜索 (DFS) 算法
void dfs(vector<vector<char>>& grid, int i, int j) {
// 如果索引超出网格范围,则返回
if (i < 0 || j < 0) {
return;
}
if (i >= grid.size() || j >= grid[0].size()) {
return;
}
// 如果当前位置是水 ('0'),则返回
if (grid[i][j] == '0') {
return;
}
// 将当前土地标记为已访问过(变为 '0')
grid[i][j] = '0';
// 递归地访问四个方向的相邻土地
dfs(grid, i + 1, j); // 向下
dfs(grid, i, j + 1); // 向右
dfs(grid, i - 1, j); // 向上
dfs(grid, i, j - 1); // 向左
}
// 计算岛屿的数量
int numIslands(vector<vector<char>>& grid) {
int c = 0; // 岛屿计数器
// 遍历网格中的每个元素
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
// 如果找到一个新的岛屿(未访问过的土地 '1')
if (grid[i][j] == '1') {
dfs(grid, i, j); // 使用DFS将整个岛屿标记为已访问
c++; // 岛屿计数 +1
}
}
}
return c; // 返回岛屿的总数
}
int main() {
// 示例网格 1
vector<vector<char>> grid1 = {
{'1', '1', '1', '1', '0'},
{'1', '1', '1', '1', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '0', '0', '0'}
};
// 计算并输出网格 1 中的岛屿数量
int res1 = numIslands(grid1);
cout << res1 << endl;
// 示例网格 2
vector<vector<char>> grid2 = {
{'1', '1', '0', '0', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '1', '0', '0'},
{'0', '0', '0', '1', '1'}
};
// 计算并输出网格 2 中的岛屿数量
int res2 = numIslands(grid2);
cout << res2 << endl;
return 0; // 程序结束
}
Java
import java.util.*;
public class Main {
// 深度优先搜索 (DFS) 算法
public static void dfs(char[][] grid, int i, int j) {
// 如果索引超出网格范围,则返回
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) {
return;
}
// 如果当前位置是水 ('0'),则返回
if (grid[i][j] == '0') {
return;
}
// 将当前土地标记为已访问过(变为 '0')
grid[i][j] = '0';
// 递归地访问四个方向的相邻土地
dfs(grid, i + 1, j); // 向下
dfs(grid, i, j + 1); // 向右
dfs(grid, i - 1, j); // 向上
dfs(grid, i, j - 1); // 向左
}
// 计算岛屿的数量
public static int numIslands(char[][] grid) {
int c = 0; // 岛屿计数器
// 遍历网格中的每个元素
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
// 如果找到一个新的岛屿(未访问过的土地 '1')
if (grid[i][j] == '1') {
dfs(grid, i, j); // 使用DFS将整个岛屿标记为已访问
c++; // 岛屿计数 +1
}
}
}
return c; // 返回岛屿的总数
}
// 主函数
public static void main(String[] args) {
// 示例网格 1
char[][] grid1 = {
{'1', '1', '1', '1', '0'},
{'1', '1', '1', '1', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '0', '0', '0'}
};
// 计算并输出网格 1 中的岛屿数量
int res1 = numIslands(grid1);
System.out.println(res1);
// 示例网格 2
char[][] grid2 = {
{'1', '1', '0', '0', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '1', '0', '0'},
{'0', '0', '0', '1', '1'}
};
// 计算并输出网格 2 中的岛屿数量
int res2 = numIslands(grid2);
System.out.println(res2);
}
}
Python3
def dfs(grid, i, j):
"""
深度优先搜索 (DFS) 算法
:param grid: 二维网格
:param i: 当前行索引
:param j: 当前列索引
"""
# 如果索引超出网格范围,则返回
if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]):
return
# 如果当前位置是水 ('0'),则返回
if grid[i][j] == "0":
return
# 将当前土地标记为已访问过(变为 '0')
grid[i][j] = "0"
# 递归地访问四个方向的相邻土地
dfs(grid, i + 1, j) # 向下
dfs(grid, i, j + 1) # 向右
dfs(grid, i - 1, j) # 向上
dfs(grid, i, j - 1) # 向左
def numIslands(grid):
"""
计算岛屿的数量
:param grid: 二维网格
:return: 岛屿的数量
"""
c = 0 # 岛屿计数器
# 遍历网格中的每个元素
for i in range(len(grid)):
for j in range(len(grid[0])):
# 如果找到一个新的岛屿(未访问过的土地 '1')
if grid[i][j] == "1":
dfs(grid, i, j) # 使用DFS将整个岛屿标记为已访问
c += 1 # 岛屿计数 +1
return c # 返回岛屿的总数
# 主函数
if __name__ == "__main__":
# 示例网格 1
grid1 = [
["1", "1", "1", "1", "0"],
["1", "1", "1", "1", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "0", "0", "0"],
]
# 计算并输出网格 1 中的岛屿数量
res1 = numIslands(grid1)
print(res1)
# 示例网格 2
grid2 = [
["1", "1", "0", "0", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "1", "0", "0"],
["0", "0", "0", "1", "1"],
]
# 计算并输出网格 2 中的岛屿数量
res2 = numIslands(grid2)
print(res2)
JsNode
function dfs(grid, i, j) {
// 如果索引超出网格范围,则返回
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) {
return;
}
// 如果当前位置是水 ('0'),则返回
if (grid[i][j] === '0') {
return;
}
// 将当前土地标记为已访问过(变为 '0')
grid[i][j] = '0';
// 递归地访问四个方向的相邻土地
dfs(grid, i + 1, j); // 向下
dfs(grid, i, j + 1); // 向右
dfs(grid, i - 1, j); // 向上
dfs(grid, i, j - 1); // 向左
}
function numIslands(grid) {
let c = 0; // 岛屿计数器
// 遍历网格中的每个元素
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[0].length; j++) {
// 如果找到一个新的岛屿(未访问过的土地 '1')
if (grid[i][j] === '1') {
dfs(grid, i, j); // 使用DFS将整个岛屿标记为已访问
c++; // 岛屿计数 +1
}
}
}
return c; // 返回岛屿的总数
}
// 示例网格 1
let grid1 = [
['1', '1', '1', '1', '0'],
['1', '1', '1', '1', '0'],
['1', '1', '0', '0', '0'],
['0', '0', '0', '0', '0']
];
// 计算并输出网格 1 中的岛屿数量
let res1 = numIslands(grid1);
console.log(res1);
// 示例网格 2
let grid2 = [
['1', '1', '0', '0', '0'],
['1', '1', '0', '0', '0'],
['0', '0', '1', '0', '0'],
['0', '0', '0', '1', '1']
];
// 计算并输出网格 2 中的岛屿数量
let res2 = numIslands(grid2);
console.log(res2);
Go
package main
import (
"fmt"
)
// 深度优先搜索 (DFS) 算法
func dfs(grid [][]byte, i, j int) {
// 如果索引超出网格范围,则返回
if i < 0 || j < 0 || i >= len(grid) || j >= len(grid[0]) {
return
}
// 如果当前位置是水 ('0'),则返回
if grid[i][j] == '0' {
return
}
// 将当前土地标记为已访问过(变为 '0')
grid[i][j] = '0'
// 递归地访问四个方向的相邻土地
dfs(grid, i+1, j) // 向下
dfs(grid, i, j+1) // 向右
dfs(grid, i-1, j) // 向上
dfs(grid, i, j-1) // 向左
}
// 计算岛屿的数量
func numIslands(grid [][]byte) int {
c := 0 // 岛屿计数器
// 遍历网格中的每个元素
for i := 0; i < len(grid); i++ {
for j := 0; j < len(grid[0]); j++ {
// 如果找到一个新的岛屿(未访问过的土地 '1')
if grid[i][j] == '1' {
dfs(grid, i, j) // 使用DFS将整个岛屿标记为已访问
c++ // 岛屿计数 +1
}
}
}
return c // 返回岛屿的总数
}
func main() {
// 示例网格 1
grid1 := [][]byte{
{'1', '1', '1', '1', '0'},
{'1', '1', '1', '1', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '0', '0', '0'},
}
// 计算并输出网格 1 中的岛屿数量
res1 := numIslands(grid1)
fmt.Println(res1)
// 示例网格 2
grid2 := [][]byte{
{'1', '1', '0', '0', '0'},
{'1', '1', '0', '0', '0'},
{'0', '0', '1', '0', '0'},
{'0', '0', '0', '1', '1'},
}
// 计算并输出网格 2 中的岛屿数量
res2 := numIslands(grid2)
fmt.Println(res2)
}