算法思想一:深度优先搜索

解题思路:

可以将二维网格看成一个无向图,竖直或水平相邻的 1 之间有边相连。
为了求出岛屿的数量,可以扫描整个二维网格。如果一个位置为 1,则以其为起始节点开始进行深度优先搜索(四周)。在深度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。
最终岛屿的数量就是我们进行深度优先搜索的次数。

图解:

代码展示:

JAVA版本

import java.util.*;
public class Solution {
    /**
     * 判断岛屿数量
     * @param grid char字符型二维数组 
     * @return int整型
     */
    // 深度优先搜索
    void dfs(char[][] grid, int r, int c) {
        int nr = grid.length;
        int nc = grid[0].length;
        // 边界限定
        if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {
            return;
        }
        // 遍历过的点变为 0
        grid[r][c] = '0';
        // 递归
        dfs(grid, r - 1, c);
        dfs(grid, r + 1, c);
        dfs(grid, r, c - 1);
        dfs(grid, r, c + 1);
    }
    public int solve (char[][] grid) {
        // write code here
        // 特殊情况
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int nr = grid.length;
        int nc = grid[0].length;
        int num_islands = 0;
        // 双层循环
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_islands;
                    // 深度递归遍历
                    dfs(grid, r, c);
                }
            }
        }
        return num_islands;
    }
}

复杂度分析

时间复杂度:其中 M 和 N 分别为行数和列数,双重遍历时间

空间复杂的:在最坏情况下,整个网格均为陆地,深度优先搜索的深度达到MN

算法思想二:广度优先搜索

解题思路:

同样地,也可以使用广度优先搜索代替深度优先搜索。
为了求出岛屿的数量,我们可以扫描整个二维网格。如果一个位置为 1,则将其加入队列,开始进行广度优先搜索。在广度优先搜索的过程中,每个搜索到的 1 都会被重新标记为 0。直到队列为空,搜索结束。
最终岛屿的数量就是我们进行广度优先搜索的次数。

代码展示:

Python版本

import collections
#
# 判断岛屿数量
# @param grid char字符型二维数组 
# @return int整型
#
class Solution:
    def solve(self , grid ):
        # write code here
        nr = len(grid)
        if nr == 0:
            return 0
        nc = len(grid[0])
        # 初始化
        num_islands = 0
        # 双层遍历
        for r in range(nr):
            for c in range(nc):
                if grid[r][c] == "1":
                    num_islands += 1
                    # 将 1 变为 0
                    grid[r][c] = "0"
                    # 将该位置加入队列
                    neighbors = collections.deque([(r, c)])
                    while neighbors:
                        # 出队列
                        row, col = neighbors.popleft()
                        for x, y in [(row - 1, col), (row + 1, col), (row, col - 1), (row, col + 1)]:
                            if 0 <= x < nr and 0 <= y < nc and grid[x][y] == "1":
                                neighbors.append((x, y))
                                grid[x][y] = "0"
        return num_islands

复杂度分析

时间复杂度:其中 M 和 N 分别为行数和列数,双重遍历时间

空间复杂的:在最坏情况下,整个网格均为陆地,队列的大小可以达到